使用XAML设置对象属性

时间:2013-01-27 20:56:22

标签: c# wpf xaml data-binding

我的项目代码中有两个自定义UserControl:TableControl和DeckControl。在后者的代码中,我可以在需要时访问前者。所以在我的DeckControl中我实现了以下属性:

private TableControl m_Table;

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

问题是我无法从XAML代码设置属性:

<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>

我尝试使用Reference但编译器说方法或歌剧

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

我试过了,但它也没有用:

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

我也尝试过使用Binding:

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

好的......这是我第一次接触XAML而且我还在努力......但我真的无法得到它!

1 个答案:

答案 0 :(得分:1)

如果要绑定到模型(window / Usercontrol)代码隐藏中的属性,则必须在DataContext中设置Xaml。 有可能实现此目的,但最简单的方法是使用ElementName命名窗口或用户控件和绑定。

窗口示例:

<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>

如果您希望在表格更改时Xaml更新后面的代码应该实现INotifyPropertyChanged,则会通知Xaml该属性已更改。

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));
        }
    }
}

如果您的Table属性不是DependancyProperty,则必须对此进行更改以便绑定。

示例:

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); }
     }
 }

在UserControl范围之外绑定的任何属性也必须是DependancyProperty。

示例:

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

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

当它是一个简单的属性时,它将绑定在usercontrol中,因为它是inscope。

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

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

这不会因为超出UserControl的范围而绑定,MyProperty必须是一个DependancyProperty才能绑定到这里

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

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

</Window>

希望有道理:)