【问题标题】:Bind property of childcontrol to parentcontrol将子控件的属性绑定到父控件
【发布时间】:2014-08-04 07:45:13
【问题描述】:

我有一个UserControl(父母),其中另一个UserControl(孩子)。我想将子控件中的属性绑定到父控件中的属性。 UserControls 都是在 MVVM 中开发的。我现在的问题是,如何在父控件的 xaml 中访问子控件的属性?

我必须在子控件的代码隐藏中做一些事情还是有其他方法?

我有一个名为 IPerson 的接口,它看起来像:

public interface IPerson
{
  string Firstname {get;set;}
  string Lastname {get;set;}
}

父控件 (PersonsView) 在左侧有一个 TreeView,在右侧有子控件 (PersonView)。

Persons-View 的 XAML 是:

<UserControl x:Class="ScM.Contents.View.PersonsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:viewModel="clr-namespace:ScM.Contents.ViewModel"
             xmlns:view="clr-namespace:ScM.Contents.View"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <viewModel:PersonsViewModel />
    </UserControl.DataContext>
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/ScM.Interface;component/GUI/ScMStyles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <view:PersonsTreeView Grid.Column="0" Margin="2"
                             OpenPupil="{Binding DataContext.OpenPersonCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
                             Persons="{Binding DataContext.Persons, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, 
            RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" />
        <GridSplitter Grid.Column="1" Width="2" ShowsPreview="True" VerticalAlignment="Stretch"
                      HorizontalAlignment="Center" Margin="0,2" />

        <view:PersonView Grid.Column="2" Margin="2"></view:PersonView>

    </Grid>
</UserControl>

Person-View 仅包含标签和文本框。 PersonViewModel 看起来像:

internal class PersonViewModel : ViewModelBase
{
    private readonly PersonModel _personModel;

    private IPerson _person;

    public PersonViewModel()
    {
        _personModel = new PersonModel();
    }

    public IPerson Person
    {
        get { return _person; }
        set
        {
            _person = value;
            OnPropertyChanged();
        }
    }
}

【问题讨论】:

  • 发布您想要访问的 XAML 代码并显示控件的层次结构。答案将取决于您的控制结构。
  • 只是备注:默认情况下继承的DataContext,所以你不应该需要那些复杂的绑定。 OpenPupil="{Binding OpenPersonCommand}" 应该没问题。

标签: c# wpf xaml mvvm user-controls


【解决方案1】:

您可以使用 ElementName 命名您的父控件以指向它

<ParentControl x:Name=ParentControl>
   <ChildControl SomeChildControlProperty="{Binding SomeParentControlProperty,
                                            ElementName=ParentControl}"/>
</ParentControl>

或者您可以将 RelativeSource 与 FindAncestor 一起使用:

<ParentControl>
   <ChildControl SomeChildControlProperty="{Binding SomeParentControlProperty,
          RelativeSource={RelativeSource FindAncestor,
                          AncestorType={x:Type ParentControl}}}"/>
</ParentControl>

我没有测试这段代码,所以语法可能不完全正确

【讨论】:

  • 问题是我想在子控件中设置的属性不在代码隐藏文件中。它在一个单独的类中。所以我不能用这个访问它。如果我尝试使用 &lt;view:PersonView Person="{Binding SelectedPerson}"/&gt; 会出现编译器错误
  • 如果不在代码隐藏文件中,则不是子控件的属性。看起来您将 Views 及其 DependencyProperties 与 ViewModels 及其标准属性以及两者之间的绑定关系混淆了。在您遇到错误的 xaml 行中,Person 应该是 PersonView 的属性,即在后面的代码中声明的依赖属性。
  • 是的。并且知道我想知道是否可以从视图绑定到 ViewModel 中的属性?还是我必须在视图的代码隐藏中引入 DependencyProperty?
  • PersonView 应设计为将PersonViewModel 视为DataContext。然后你会得到:&lt;view:PersonView DataContext="{Binding SelectedPerson}"/&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多