我正在使用MVVM做一个简单的WPF应用程序,我无法绑定到组合框的SelectedItem属性。 绑定属性的setter不会被调用,并且调试窗口中没有输出告诉我它无法绑定(我认为它能够)。 这是.NET 3.5,我做了一个小例子,它有同样的问题。
在XAML中:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<ComboBox IsDropDownOpen="False" IsReadOnly="False" ItemsSource="{Binding Path=Printers}" SelectedIndex="0" SelectedItem="{Binding Path=Printer.SelectedPrinter, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Name="cmbPrinters" />
</StackPanel>
</Window>
查看背后的代码:
using System.Windows;
public partial class Window1 : Window
{
ViewModel viewmodel;
public Window1()
{
viewmodel = new ViewModel();
this.DataContext = viewmodel;
InitializeComponent();
}
}
查看型号:
using System;
using System.Collections.ObjectModel;
public class ViewModel
{
public ViewModel()
{
Printers = new ObservableCollection<string>() { "test", "test2" };
Printer = new PrinterViewModel();
}
public PrinterViewModel Printer { get; set; }
public ObservableCollection<string> Printers { get; set; }
}
PrinterViewModel:
using System.Windows;
using System.Diagnostics;
public class PrinterViewModel : DependencyObject
{
public string SelectedPrinter
{
get { return (string)GetValue(SelectedPrinterProperty); }
set
{
SetValue(SelectedPrinterProperty, value);
Debug.WriteLine("!!!!!! SelectedPrinter setter called");
}
}
public readonly DependencyProperty SelectedPrinterProperty =
DependencyProperty.Register("SelectedPrinter", typeof(string), typeof(PrinterViewModel), new UIPropertyMetadata());
}
谁能看到我在这里做错了什么?
答案 0 :(得分:2)
这里的问题是您对Silverlight依赖属性系统的工作方式存在误解。
当依赖项属性的值更改时,Silverlight不会遍历您定义的属性(例如SelectedPrinter
)来设置依赖项属性的值。 Silverlight依赖项属性机制会跟踪依赖项属性的所有值,当其中一个属性的值发生更改时,Silverlight会直接更改其值,而不会调用您的代码来执行此操作。特别是,它不会调用您的属性设置器。这可以解释为什么你的调试信息没有出现。
使用依赖项属性的属性中的getter(例如SelectedPrinter
属性)应仅包含对GetValue
的调用,并且setter应仅包含对SetValue
的调用。您不应该向getter或setter添加任何代码,因为这样做无法达到您想要的效果。
此外,您正在视图模型层中使用依赖项属性。这不是他们打算使用的地方。依赖项属性仅用于视图层。您的视图模型类应该是implementing INotifyPropertyChanged
,而不是扩展DependencyObject
。
可以将两个依赖项属性绑定在一起。这是允许的,有时在视图层中将两个依赖项属性连接在一起非常有用。事实上,您的示例中的绑定正在工作,这解释了为什么您没有收到有关绑定问题的任何消息。
答案 1 :(得分:1)
为什么在执行mvvm时从DependencyObject继承?`
public class PrinterViewModel : INotifyPropertyChanged
{
private string _selected;
public string SelectedPrinter
{
get { return this._selected; }
set
{
_selected= value;
OnPropertyChanged("SelectedPrinter");
}
}
}
现在您的代码应该正常工作