Silverlight 3用户控制数据绑定在xaml中

时间:2009-08-09 13:14:23

标签: silverlight data-binding user-controls

我正在努力实现一些在概念上非常简单但似乎无法实现的东西。

我有一个名为c1的类,它有2个依赖属性,一个整数I和一个字符串S.它实现了INotifiyPropertyChanged。

public class c1: INotifyPropertyChanged 
{
    private int i;
    public int I { get { return i; } set { i = value; if(PropertyChanged != null) PropertyChanged(this,new PropertyChangedEventArgs("I")); } }
    private string s;
    public string S { get { return s; } set { s = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("S")); } }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

此类由Silverlight用户控件SUC引用,该控件也将INotifiyPropertyChanged实现为依赖属性C,具有PropertyChangedCallback等。如下所示。

public partial class SUC : UserControl, INotifyPropertyChanged
{

    public c1 C
    {
        get { return (c1)GetValue(CProperty); }
        set { SetValue(CProperty, value); }
    }
    public static readonly DependencyProperty CProperty =
        DependencyProperty.Register("C", typeof(c1), typeof(SUC), new PropertyMetadata(new c1(), new PropertyChangedCallback(c1Changed)));


    private static void c1Changed(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        SUC s = obj as SUC;
        if (s != null)
            s.CChanged((c1)e.NewValue);
    }

    public void CChanged(c1 c)
    {
        C = c;
        if(PropertyChanged!=null)
            PropertyChanged(this,new PropertyChangedEventArgs("C"));
    }
    public SUC()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private void bclick(object sender, RoutedEventArgs e)
    {
        C.S = C.S + " Clicked";
        MessageBox.Show(C.I.ToString() + " - " + C.S);
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

在我的主页面中也实现了INotifiyPropertyChanged我有一个c1和SUC的实例。

public partial class MainPage : UserControl, INotifyPropertyChanged
{


    public c1 MC
    {
        get { return (c1)GetValue(MCProperty); }
        set { SetValue(MCProperty, value); }
    }

    public static readonly DependencyProperty MCProperty =
        DependencyProperty.Register("MC", typeof(c1), typeof(MainPage), new PropertyMetadata(new c1()));


    private static void MCChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MainPage mp = d as MainPage;
        if (mp != null)
            mp.MCChanged();
    }

    public void MCChanged()
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("MC"));
    }

    public MainPage()
    {
        InitializeComponent();
        MC.S = "ssss";
        this.DataContext = this;
    }


    public event PropertyChangedEventHandler PropertyChanged;

}

我想通过XAML设置SUC用户控件的C属性。像这样

local:SUC x:Name =“suc”C =“{Binding MC,Mode = TwoWay}”

这在后面的c#代码中很有效,但在XAML中却没有。我在XAML中需要它的原因是因为我想将一个c1的集合绑定到DataTemplate中的SUC。

任何带有可下载代码的工作示例都将非常受欢迎。

3 个答案:

答案 0 :(得分:1)

这是SUC类构造函数中的一个简单的小错误:

    public SUC()
    {
        InitializeComponent();
        this.DataContext = this; //this line shouldn't be here, delete and it will work
    }

这意味着SUC控件的DataContext本身而不是MainPage类,它是绑定到MainPage.MC所需要的(SUC类没有MC属性)。

另外,我意识到其中大部分是你可能只是想让它发挥作用,但MC不需要成为DP,你不需要'C = c;'在SUC中的行,我也不会将MainPage控件类用作datacontext类,创建另一个类来绑定DataContext。

答案 1 :(得分:0)

问题似乎是在加载XAML后设置DataContext UserControl。在加载XAML之前设置它(即在InitializeComponent之前),或者甚至更好,在XAML中设置它:

<local:MainPage ... DataContext="{Binding RelativeSource={RelativeSource Self}}">
    ....
</local:MainPage>

RelativeSource绑定指定DataContext的{​​{1}}应该是自己的,这似乎就是您想要的。这样就消除了代码隐藏中MainPage的赋值,这在WPF / Silverlight中总是一件好事。

希望有所帮助。

答案 2 :(得分:0)

UserControl控件的DataContext可以与UserControl本身或UserControl的Parent“Form”(或Parent Page,UserControl)不同。您必须在Code Behind中设置Binding。有关详情,请参阅此帖子:Silverlight UserControl Custom Property Binding

此外,您可能想要创建Silverlight Control 而不是Silverlight UserControl