views:

524

answers:

5

Let's take a very simple example:

  • In my window1.xaml, i have a label control named 'lblProduct'.
  • In my window1.xaml.cs, i have a public method called CalculateProduct(Int Var1, Int Var2). CalculateProduct will, as you may have guessed, calculate the product of the variables passed in.

I'd like to simply bind the results of 'CalculateProduct' to my label. My actual use case is a little more complicated than this. However, if I could get this up and running not only would I be quite happy, I'd be able to figure out the rest.

I've seen interesting examples using the ObjectDataProvider to bind to a static method of a new class. While this is well and good, I don't feel the need to create a new class when I've already instantiated the one for my window. In addition, there may be other global variables that I'd like to take advantage of in my Window1 class.

Thanks for your time and help,

Abel.

+1  A: 

ObjectDataProvider has an ObjectInstance property that you can assign your Window instance to.

HTH, Kent

Kent Boogaart
Given my example, what would i set ObjectInstance to? 'Window1' and 'this' won't work.
Abel Martin
+3  A: 

It's quick and dirty but I'd probably just have CalculateProduct set a property with its result and databind to the property.

Bryan Anderson
Thanks, I thought about this as a solution, but I was hoping that I was missing some uber-simple way of doing this. Great thought though.
Abel Martin
+2  A: 

Yes, there is a way. It's not pretty. You have to add an xmlns:Commands attribute to your window1.xaml tag. I ended up bastardizing some code I found in this Code Project article.

Is the product that you want to display in the label something that's generated on load, or from another control event?

I'm not sure this will help you, but I ran into something similar where I was trying to generate XAML dynamically with XSLT. My solution worked, kind of...well, not really for what I was trying to do. But maybe it will help you.

As I said, you have to declare the xmlns in your page tag, like so:

<Page x:Class="WpfBrowserApplication1.Page1" 
  blah blah blah 
  xmlns:Commands="clr-namespace:WpfBrowserApplication1">

Then, define a static class in your application with the same namespace, pretty much the same as the example in the Code Project article, with handlers for a RoutedUICommand:

namespace WpfBrowserApplication1
{
    public static class CommandHandlers
    {
        private static System.Windows.Input.RoutedUICommand _submitCommand;

        static CommandHandlers()
        {
            _submitCommand = new System.Windows.Input.RoutedUICommand("Submit", "SubmitCommand", typeof(CommandHandlers));
        }

        public static void BindCommandsToPage(System.Windows.Controls.Page caller)
        {
            caller.CommandBindings.Add(new System.Windows.Input.CommandBinding(SubmitCommand, SubmitContact_Executed, SubmitContact_CanExecute));
        }

        public static System.Windows.Input.RoutedUICommand SubmitCommand
        {
            get { return _submitCommand; }
        }

        public static void SubmitContact_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
        {
            ...do stuff...
        }

        public static void SubmitContact_CanExecute(object sender, System.Windows.Input.CanExecuteRoutedEventArgs e)
        {
            if (e.Source is System.Windows.Controls.Button)
                e.CanExecute = true;
            else
                e.CanExecute = false;
        }
    }
}

The nasty part is that, so far as I've found, the only way to map things back to Page1.xaml is to cast the sender object and dig through the UI elements of the Page, similar to how you would dig through the DOM on a web page. I had some success with this, but certainly don't pretend to be an expert.

The last thing you have to do is wire up your control in the Page1.xaml.cs. In the XAML, you do it like so:

<Button Name="btnSubmit" Command="Commands:CommandHandlers.SubmitCommand" etc... />

In the code-behind, like so:

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    CommandHandlers.BindCommandsToPage(this);
}

I hope that helps, and good luck.

AJ
This is an excellent plan B. The current state of the code is decent. I hadn't thought of simply moving all my interactions into a static helper class if it makes WPF binding happy. It just feels so very odd, but i can get over it if necessary.
Abel Martin
I can't wait to hear more about the bastard ;-)
Abel Martin
I'm not certain if this is what you're looking for, but I thought it might help.
AJ
This will do just fine! I'm trying to release my preconceived notions on what i want to do and I'm beginning to accept what i need to do. Thanks dude!
Abel Martin
+1  A: 

Why you not just set the label value in your CalculateProduct method before you return from the method. Basically way do you need data binding here? It is one way anyhow, since you are binding to a label.

aogan
A: 

aogan: The idea here is to leverage the flexibility of WPF databinding. I could set the entire UI in the code behind, but MS has developed this binding system and i wanted to easily take advantage of it. Also, this was a simple example for a more complicated problem.

To everyone else involved, i've gone with PITAdev's solution. Thanks for the help.

Abel Martin