我正在努力实现一些在概念上非常简单但似乎无法实现的东西。
我有一个名为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。
任何带有可下载代码的工作示例都将非常受欢迎。
答案 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