我正在开发一个WPF应用程序,我正在努力了解DataContext的一些细节,因为它适用于绑定。我的应用程序使用一个业务对象,其定义如下:
public class MyBusinessObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
// enumerations for some properties
public enum MyEnumValues
{
[Description("New York")]
NewYork,
[Description("Chicago")]
Chicago,
[Description("Los Angeles")]
LosAngeles
}
// an example property
private string _myPropertyName;
public string MyPropertyName
{
get { return _myPropertyName; }
set
{
if (_myPropertyName == value)
{
return;
}
_myPropertyName = value;
OnPropertyChanged(new PropertyChangedEventArgs("MyPropertyName"));
}
}
// another example property
private MyEnumValues _myEnumPropertyName;
public MyEnumValues MyEnumPropertyName
{
get { return _myEnumPropertyName; }
set
{
if (_myEnumPropertyName== value)
{
return;
}
_myEnumPropertyName= value;
OnPropertyChanged(new PropertyChangedEventArgs("MyEnumPropertyName"));
}
}
// example list property of type Widget
public List<Widget> MyWidgets { get; set; }
// constructor
public MyBusinessObject()
{
// initialize list of widgets
MyWidgets = new List<Widget>();
// add 10 widgets to the list
for (int i = 1; i <= 10; i++)
{
MyWidgets.Add(new Widget());
}
// set default settings
this.MyPropertyName = string.empty;
}
}
如您所见,我有一些在此类中声明的属性,其中一个是Widgets列表。 Widget类本身也实现了INotifyPropertyChanged并公开了大约30个属性。
我的UI有一个组合框,它绑定到我的Widgets列表,如下所示:
MyBusinessObject myBusinessObject = new MyBusinessObject();
public MainWindow()
{
InitializeComponent();
this.DataContext = myBusinessObject;
selectedWidgetComboBox.ItemsSource = myBusinessObject.MyWidgets;
selectedWidgetComboBox.DisplayMemberPath = "WidgetName";
selectedWidgetComboBox.SelectedValuePath = "WidgetName";
}
我的UI上的大多数控件都用于显示Widget的属性。当我的用户从组合框中选择一个Widget时,我希望这些控件显示所选Widget的属性。我目前通过在我的组合框的SelectionChanged事件处理程序中更新我的窗口的DataContext来实现此行为,如下所示:
private void selectedWidgetComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.DataContext = selectedWidgetComboBox.SelectedItem;
}
这允许我将我的控件绑定到适当的Widget属性,如下所示:
<TextBox Text="{Binding WidgetColor}"></TextBox>
但是,并非我的UI中的所有控件都用于显示窗口小部件属性。某些控件需要显示MyBusinessObject的属性(例如:上面定义的MyPropertyName)。在这种情况下,我不能简单地说:
<TextBox Text="{Binding MyPropertyName}"></TextBox>
...因为窗口的DataContext指向选定的Widget而不是MyBusinessObject。谁能告诉我如何为特定控件(在XAML中)设置DataContext以引用MyPropertyName属于MyBusinessObject的属性?谢谢!
答案 0 :(得分:3)
您应该向MyBusinessObject类添加一个属性,而不是更改窗口的DataContext:
private Widget _selectedWidget;
public Widget SelectedWidget
{
get { return _selectedWidget; }
set
{
if (_selectedWidget == value)
{
return;
}
_selectedWidget = value;
OnPropertyChanged(new PropertyChangedEventArgs("SelectedWidget"));
}
}
然后将SelectedWidget绑定到组合框的SelectedItem属性。您需要使用小部件属性的任何地方,您可以这样做:
<TextBox Text="{Binding Path=SelectedWidget.WidgetColor}"></TextBox>
答案 1 :(得分:1)
尝试
<TextBox Text="{Binding MyBusinessObject.MyPropertyName}"></TextBox>
如果MyBusinessObject是文本框的datacontext而MyPropertyName是MyBusinessObject的属性
,则此方法有效此外,Here is a good article to clarify binding
希望这会有所帮助
使用这样的相对绑定:
text="{Binding DataContext.MyPropertyName, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TypeOfControl}}}"
因此,relatve绑定允许您将可视树查找到另一个UI元素并使用其datacontext。我会考虑将窗口的内容包装在网格中。并将windows datacontext润湿到businessobject,将网格datacontext润湿到小部件。这样,您始终可以通过实际源绑定使用父窗口的datacontext。
如果您的窗口的datacontext是您的业务对象,请使用以下内容
text="{Binding DataContext.MyPropertyName, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"