当在父元素上设置了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);
        }
    }
}

当在父元素上设置了datacontext时,如何覆盖或更改子元素的继承

好吧,你可以做各种事情,比如在所有较低的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,它将"自动"显示您想要的内容。