如何让我的 WPF 用户控件的依赖属性更新我的视图模型?
Posted
技术标签:
【中文标题】如何让我的 WPF 用户控件的依赖属性更新我的视图模型?【英文标题】:How do I make my WPF User Control's dependency properties update my view model? 【发布时间】:2011-04-22 15:04:36 【问题描述】:我正在尝试创建一个具有要绑定的依赖属性的用户控件。在内部,我有一个绑定到这些相同属性的ComboBox
,但绑定只能以一种方式工作。 ComboBox
从 ItemsSource
填充,但 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>
用户控件中的组合框填充了名称,但是当我选择不同的名称时,它不会更新回视图模型。知道我在这里缺少什么吗?
谢谢!
【问题讨论】:
【参考方案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() 方法。以上是关于如何让我的 WPF 用户控件的依赖属性更新我的视图模型?的主要内容,如果未能解决你的问题,请参考以下文章
如何绑定只读的 WPF 控件属性(例如 ActualWidth),以便在视图模型中可以访问其值? [复制]
Caliburn.Micro-如何从继承的ViewModel在WPF视图中显示多个项目:Conductor 。Collection.AllActive