2012-07-20 94 views
0

我正在做一个简单的WPF应用程序使用MVVM和我有麻烦绑定到组合框的SelectedItem属性。 绑定属性的setter不会被调用,并且在调试窗口中没有输出告诉我它不能绑定(我认为它能够)。 这是.NET 3.5,我做了一个小例子,它有同样的问题。Combobox.SelectedItem绑定到嵌套属性

在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

不要混合'SelectedIndex'和'SelectedItem'。这给了麻烦。 – LPL 2012-07-20 09:22:30

+0

好的,但没有任何效果,现在组合框显示为空,当我启动应用程序。 – 2012-07-20 09:29:23

+0

是的,我添加了PrinterViewModel代码 – 2012-07-20 09:31:52

回答

2

这里的问题是,你有一个关于Silverlight的依赖属性系统是如何工作的误解。

当依赖项属性的值发生变化时,Silverlight不会检查您定义的属性(例如SelectedPrinter)来设置依赖项属性的值。 Silverlight依赖项属性机制会跟踪依赖项属性的所有值,并且当其中一个属性的值发生更改时,Silverlight会直接更改其值,而无需调用您的代码。特别是,它不会打电话给你的财产制定者。这应该解释为什么你的调试信息没有出现。

在使用依赖项属性,属性的吸附剂,如您SelectedPrinter财产,应包含只GetValue一个电话,二传手应该包含只SetValue通话。你不应该向getter或setter添加任何代码,因为这样做不会达到你想要的。

此外,您在视图模型图层中使用依赖属性。这不是他们打算使用的地方。依赖属性仅用于视图层。您的视图模型类应改为implementing INotifyPropertyChanged,而不要延伸DependencyObject

可以将两个依赖项属性绑定在一起。这是允许的,偶尔它有助于将视图层中的两个依赖属性连接在一起。事实上,你的例子中的绑定工作正常,这就解释了为什么你没有收到有关绑定问题的消息。

+0

+1 thx作为解释 – blindmeis 2012-07-20 13:07:01

+0

不错,删除了依赖项属性并删除了SelectedPrinter属性中的SetValue/GetValue,现在它工作。 – 2012-07-20 15:52:30

1

为什么自DependencyObject做MVVM当继承?`

public class PrinterViewModel : INotifyPropertyChanged 
{ 
    private string _selected; 
    public string SelectedPrinter 
    { 
     get { return this._selected; } 
     set 
     { 
     _selected= value; 
     OnPropertyChanged("SelectedPrinter"); 
     } 
    } 
} 

现在您的代码应工作