xaml中的Silverlight 3用户控件数据绑定

xaml中的Silverlight 3用户控件数据绑定,silverlight,data-binding,user-controls,Silverlight,Data Binding,User Controls,我试图实现一些概念上非常简单但似乎无法实现的东西 我有一个名为c1的类,它有两个依赖属性,一个整数I和一个字符串S。它实现了InotifyPropertyChanged public class c1: INotifyPropertyChanged { private int i; public int I { get { return i; } set { i = value; if(PropertyChanged != null) PropertyChanged(this,

我试图实现一些概念上非常简单但似乎无法实现的东西

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

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引用,该控件还将InotifyPropertyChanged实现为依赖属性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;
}
在我的主页上,也实现了InotifyPropertyChanged,我有一个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


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

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

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

....
RelativeSource
绑定指定
MainPage
DataContext
应该是它自己,这似乎就是您想要的。这样就消除了在代码隐藏中分配
DataContext
,这在WPF/Silverlight中总是一件好事


希望能有所帮助。

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

    public SUC()
    {
        InitializeComponent();
        this.DataContext = this; //this line shouldn't be here, delete and it will work
    }
这意味着SUC控件的DataContext是自身,而不是MainPage类,MainPage类是绑定到MainPage.MC所需要的(SUC类没有MC属性)


而且,我意识到其中大多数都是你可能只是想让它工作,但是MC不需要是DP,你不需要'C=C;'在SUC中的第行,我不会将MainPage控件类也用作datacontext类,创建另一个类来绑定datacontext

UserControl控件的DataContext可以不同于UserControl本身或UserControl的父“表单”(或父页面,UserControl)。您必须在代码隐藏中设置绑定。有关更多信息,请参阅本文:


另外,您可能需要创建Silverlight控件,而不是Silverlight用户控件

谢谢您的回复。事实证明,在InitializeComponent之前设置DataContext会导致在调用InitializeComponent之后将DataContext设置为主页的DataContext。这里的问题是(正如mattmanser在下面提到的)用户控件的DataContext最终没有C属性,并且没有在XAML中绑定到它。感谢mattmanser的回复。我不明白为什么一个UserControl不能有一个单独的DataContext和它正在使用的页面。我只需要主页和用户控件共享一个变量,然后它们是两个独立的实体。我认为使用一个公共类作为页面和用户控件的DataContext是一个可行的选择(尽管这感觉像是一种折衷),这就是它的工作原理。控件是UI元素,而不是业务对象。您应该将控件绑定到单独的业务对象。请在此处查看MVC/MVVM模式和MS对数据绑定的解释:。