rsgmon
rsgmon

Reputation: 1932

Change The Binding Source To Another CLR Object

This is a mostly out of curiosity question and to hopefully help me better understand binding, XAML, and extension syntax.

So I simply want to change the binding source from the MainWindow to an object I have instantiated in MainWindow.

Here is my C# code:

    public partial class MainWindow : Window, INotifyPropertyChanged
    {

        public MainWindow()
        {
            favclass myfavclass = new favclass();
            InitializeComponent();
            this.DataContext = this;
        }

        string _myString = "hello";
        public string MyString
        {
            get { return _myString; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(
                    this, new PropertyChangedEventArgs(propName));
        }


    }

    public class favclass : INotifyPropertyChanged
    {
        int _myint = 34;
        public int MyInt
        {
            get { return _myint; }
            set { _myint = value; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(
                    this, new PropertyChangedEventArgs(propName));
        }


    }


}

and my XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" >
    <Grid>
        <TextBlock Height="50" Width="50" Text="{Binding MyString}"/>
        <TextBlock Height="50" Width="48" Margin="200,100,100,100" 
                   Text="{Binding Source=myfavclass, Path=MyInt}"/>

    </Grid>
</Window>

So as you can see I want first display the MyString property from main window.

Then I want to display the MyInt from the myfavclass object. But of course MyInt doesn't appear. I've tried every variation I can think of.

What XAML am I missing? Why doesn't the XAML I have work?

Thanks

Upvotes: 0

Views: 214

Answers (2)

King King
King King

Reputation: 63327

Source=myfavclass this is wrong. Source can be only assigned directly using element syntax like this:

<Binding>
   <Binding.Source>
       <!-- value here -->
   </Binding.Source>
</Binding>

Or you can use StaticResource or DynamicResoure or some custom MarkupExtension like this:

Text="{Binding Source={StaticResource someKey}, Path=MyInt}"

Or use the new feature {x:Reference} to get reference directly to some named element inside XAML:

Text="{Binding Source={x:Reference someName}, Path=MyInt}"

Moreover the myfavclass is declared as local variable inside your code behind. There is no way it can be used (referenced) inside XAML code.

You're doing something called multiple viewmodels. If so you should provide multiple DataContext for your controls. I prefer to using nested viewmodels. To implement this, you can try modifying the MainWindow like this:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        _myfavclass = new favclass();
        InitializeComponent();
        this.DataContext = this;
    }
    private readonly favclass _myfavclass;
    //we will use this property inside XAML code
    public favclass MyFavClass {
        get {
           return _myfavclass;
        }
    }
}

Now in XAML code, you can bind the Text to the MyFavClass.MyInt, note that the DataContext is implicitly the source for the Binding, so you just need to specify the Path:

<TextBlock Height="50" Width="48" Margin="200,100,100,100" 
               Text="{Binding Path=MyFavClass.MyInt}"/>

Your MyInt is not properly implemented using INotifyPropertyChanged (but I hope you already know that).

Upvotes: 1

Andrew Carl
Andrew Carl

Reputation: 822

favclass myfavclass = new favclass(); should be declared out of the init method,or you won't get this.myfavclass instance

Upvotes: 1

Related Questions