【问题标题】:How do I make my WPF User Control's dependency properties update my view model?如何让我的 WPF 用户控件的依赖属性更新我的视图模型?
【发布时间】:2011-04-22 15:04:36
【问题描述】:

我正在尝试创建一个具有要绑定的依赖属性的用户控件。在内部,我有一个绑定到这些相同属性的ComboBox,但绑定只能以一种方式工作。 ComboBoxItemsSource 填充,但 SelectedItem 不会更新回我绑定到的视图模型。

一个简化的例子:

这是与用户控件绑定的视图模型:

public class PeopleViewModel : INotifyPropertyChanged
{
    public PeopleViewModel()
    {
        People = new List<string>( new [] {"John", "Alfred","Dave"});
        SelectedPerson = People.FirstOrDefault();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private IEnumerable<string> _people;
    public IEnumerable<string> People 
    { 
        get { return _people; } 
        set
        {
            _people = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("People"));
            }
        }
    }

    private string _selectedPerson;
    public string SelectedPerson 
    {
        get { return _selectedPerson; }
        set 
        { 
            _selectedPerson = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("SelectedPerson"));
            }
        } 
    }
}

这是用户控件:

<UserControl x:Class="PeopleControlTest.PeopleControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         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="56" d:DesignWidth="637">
<StackPanel >
    <ComboBox Margin="11"
              ItemsSource="{Binding BoundPeople, RelativeSource={RelativeSource AncestorType=UserControl}}"
              SelectedItem="{Binding BoundSelectedPerson, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</StackPanel>

后面有代码

public partial class PeopleControl : UserControl
{
    public PeopleControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty BoundPeopleProperty =
        DependencyProperty.Register("BoundPeople", typeof(IEnumerable<string>), typeof(PeopleControl), new UIPropertyMetadata(null));

    public static readonly DependencyProperty BoundSelectedPersonProperty =
        DependencyProperty.Register("BoundSelectedPerson", typeof(string), typeof(PeopleControl), new UIPropertyMetadata(""));

    public IEnumerable<string> BoundPeople
    {
        get { return (IEnumerable<string>)GetValue(BoundPeopleProperty); }
        set { SetValue(BoundPeopleProperty, value); }
    }

    public string BoundSelectedPerson
    {
        get { return (string)GetValue(BoundSelectedPersonProperty); }
        set { SetValue(BoundSelectedPersonProperty, value); }
    }
}

这就是我在主窗口中绑定用户控件的方式(将 windows 数据上下文设置为视图模型的实例)

<Window x:Class="PeopleControlTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:controls="clr-namespace:PeopleControlTest"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <controls:PeopleControl 
            BoundPeople="{Binding People}" 
            BoundSelectedPerson="{Binding SelectedPerson}"/>
    </Grid>
</Window>

用户控件中的组合框填充了名称,但是当我选择不同的名称时,它不会更新回视图模型。知道我在这里缺少什么吗?

谢谢!

【问题讨论】:

    标签: wpf binding user-controls


    【解决方案1】:

    某些属性默认绑定双向(包括SelectedItem),但您的BoundSelectedPerson 没有。您可以设置绑定的模式:

       <controls:PeopleControl 
                BoundPeople="{Binding People}" 
                BoundSelectedPerson="{Binding SelectedPerson, Mode=TwoWay}"/>
    

    或者您可以通过在DependencyProperty 上设置一个标志来默认设置为双向:

        public static readonly DependencyProperty BoundSelectedPersonProperty =
            DependencyProperty.Register("BoundSelectedPerson", typeof(string), typeof(PeopleControl), new FrameworkPropertyMetadata("",FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    

    【讨论】:

    • 太好了,谢谢,这行得通!!!出于某种原因,我认为我读过所有 DP 默认以两种方式工作。我也在使用 UIPropertyMetadata,但我找不到那个选项。
    • (这个解决方案很好。我只是想为可能遇到同样问题的人添加一个注释,并在寻找解决方案时在这里找到他们的方式。)绑定到 UserControl 的依赖属性的属性必须具有 set() 方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多