当在父元素上设置了datacontext时,如何覆盖或更改子元素的继承
本文关键字:元素 覆盖 继承 设置 datacontext 何覆盖 | 更新日期: 2023-09-27 18:20:31
免责声明我觉得这是一个相当简单的问题,所以我必须重申,我确实在寻找答案,但什么都找不到!
不确定我问的问题是否正确,但我会告诉你这一点。我正在努力变得更加熟悉MVVM,所以我正在处理一个简单得离谱的项目,其中包括两个堆叠面板、十个文本框和一些简单的绑定。现在一切都正常了,因为我有两个面板,它们将我的框分隔开,并允许我设置两个数据上下文。
我的问题是:
a) 是否可以在父元素(Stackpanel)上设置数据上下文,让我的一半子元素(文本框)通过继承使用该上下文,然后给另一半元素一个不同的数据上下文?
和
b) 如果这是可能的,怎么做??
感谢人民——比我聪明
这是一个代码,它正在努力尝试,但没有真正做任何我想做的事情:
XAML
<Grid>
<StackPanel>
<StackPanel HorizontalAlignment="Left" Margin="8,8,0,75" Width="224" DataContext="{Binding Path=Customer}">
<TextBox Text="{Binding Path=FirstName}" Height="28" Name="label1"/>
<TextBox Text="{Binding Path=MiddleName}" Height="28" Name="l2"/>
<TextBox Text="{Binding Path=LastName}" Height="28" Name="l3"/>
<TextBox Text="{Binding Path=CompanyName}" Height="28" Name="l4"/>
<TextBox Text="{Binding Path=EmailAddress}" Height="28" Name="l5"/>
<!--I want the next five TextBox elements to bind to a different datacontext-->
<TextBox Text="{Binding Path=FirstName}" Height="28" Name="label11"/>
<TextBox Text="{Binding Path=MiddleName}" Height="28" Name="l21"/>
<TextBox Text="{Binding Path=LastName}" Height="28" Name="l1lgh3"/>
<TextBox Text="{Binding Path=CompanyName}" Height="28" Name="l1hj4"/>
<TextBox Text="{Binding Path=EmailAddress}" Height="28"/>
</StackPanel>
</StackPanel>
</Grid>
C#背后的代码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new MainViewModel();
}
}
查看模型
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
PopulateCustomerInfo();
}
private Customer customer;
public Customer Customer
{
get { return customer; }
set
{
customer = value;
OnPropertyChanged("Customer");
}
}
private Customer customer2;
public Customer Customer2
{
get { return customer2; }
set
{
customer2 = value;
OnPropertyChanged("Customer");
}
}
private void PopulateCustomerInfo()
{
AdventureWorksLTE ctx = new AdventureWorksLTE();
this.Customer = (from c in ctx.Customers
select c).FirstOrDefault();
this.Customer2 = (from c in ctx.Customers
orderby c.FirstName descending
select c).FirstOrDefault();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handle = PropertyChanged;
if (handle != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handle(this, e);
}
}
}
好吧,你可以做各种事情,比如在所有较低的TextBoxes
:上本地更改DataContext
<TextBox Text="{Binding Path=FirstName}" DataContext="..."/>
但真正的问题是:你想实现什么?在StackPanel上设置DataContext有意义吗?
也许你不应该使用更长的路径:
<TextBox Text="{Binding Path=Customer.FirstName}" Height="28" Name="label1"/>
这完全取决于将在子控件中使用哪些属性,如果它们中的大部分或全部都在Customer
中,请将其设置为保持绑定较短。如果在某些地方需要主视图模型,则可以使用RelativeSource
获取具有正确数据上下文的控件,并相应地更改路径。(DataContext.*
,数据上下文显示在路径中,因为指定了不同的源)
最简单的方法是在第一个StackPanel中有两个StackPanels,将5乘5的文本框分组,第一个文本框将customer作为数据上下文,第二个文本框具有customer2。
stackPanel和(5个文本框)内容甚至可以定义为DataTemplate(没有键或名称,而是DataType={x:Typelocal:Customer}(其中local是您的clr命名空间)),您只需要使用2个内容绑定到Customer/Customer2的ContentPresenter,它将"自动"显示您想要的内容。