Tommaso Belluzzo
Tommaso Belluzzo

Reputation: 23685

Setting an object property with XAML

I have two custom UserControl in my project code: TableControl and DeckControl. In the code of the latter I would be able to access the former when it's needed. So in my DeckControl I implemented the following property:

private TableControl m_Table;

public TableControl Table
{
    get { return m_Table; }
    set { m_Table = value; }
}

The problem is that I'm not able to set the property from XAML code:

<Canvas Core:Name="Layout" Loaded="OnLayoutLoaded">
    <Namespace:TableControl Core:Name="Table" Canvas.Left="0" Canvas.Top="0" Height="{Binding ElementName=Layout, Path=ActualHeight}" Width="{Binding ElementName=Layout, Path=ActualWidth}"/>
    <Namespace:DeckControl Core:Name="Deck" Canvas.Left="50">
</Canvas>

I tried using Reference but compiler says that the method or opera

<Namespace:DeckControl Core:Name="Deck" Canvas.Left="50" Table="{Core:Reference Name=Table}">

I tried this but it isn't working either:

<Namespace:DeckControl Core:Name="Deck" Canvas.Left="50" Table="{Core:Static Table}">

I also tried using Binding:

<Namespace:DeckControl Core:Name="Deck" Canvas.Left="50" Table="{Binding ElementName=Table}">

Ok so... it's my first approach to XAML and I'm still working on it... but I really can't get it!

Upvotes: 0

Views: 5705

Answers (1)

sa_ddam213
sa_ddam213

Reputation: 43636

If you want to bind to a property in youe Model(window/Usercontrol) codebehind you have to set the DataContext in your Xaml. There are may ways to do this but the simpliest is just naming your window or usercontrol and binding using ElementName.

Example for a Window:

<Window x:Class="WpfApplication8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="233" Width="143" Name="UI">

    <Canvas DataContext="{Binding ElementName=UI}" > <!-- Set dataContext to Window -->
        <Namespace:DeckControl Canvas.Left="50" Table="{Binding ElementName=Table}">
    </Canvas>
</Window>

And if you want the Xaml to update when Table changes your code behind should implement INotifyPropertyChanged, this will inform the Xaml that the property has changed.

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private TableControl m_Table;

    public TableControl Table
    {
       get { return m_Table; }
       set { m_Table = value; NotifyPropertyChanged("Table"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

If your Table property is not a DependancyProperty you will have to chage this so you can bind.

Example:

public class DeckControl : UserControl
 {
     .......



     // Using a DependencyProperty as the backing store for Table.  This enables animation, styling, binding, etc...
     public static readonly DependencyProperty TableProperty =
         DependencyProperty.Register("Table", typeof(TableControl), typeof(DeckControl), new UIPropertyMetadata(null));

     public TableControl Table
     {
         get { return (TableControl)GetValue(TableProperty); }
         set { SetValue(TableProperty, value); }
     }
 }

Also any property that is being binded outside the scope of the UserControl has to be a DependancyProperty.

Example:

public partial class DeckControl : UserControl
{
    public DeckControl()
    {
        InitializeComponent();
    }

    private int myVar;
    public int MyProperty
    {
        get { return myVar; }
        set { myVar = value; }
    }
}

This will bind inside the usercontrol when it is a simple property as it is inscope.

<UserControl .....
             d:DesignHeight="300" d:DesignWidth="300" Name="UI">

    <TextBlock Text="{Binding MyProperty}" />
</UserControl>

This will not bind as its out of scope of the UserControl, MyProperty will have to be a DependancyProperty to bind here

<Window ....
        Title="MainWindow" Height="233" Width="143" Name="UI">

    <Grid>
        <local:DeckControl MyProperty="{Binding Width}"  /> // Will not bind
    </Grid>

</Window>

Hope that makes sense :)

Upvotes: 1

Related Questions