0

我正在使用 MVVM 做一个简单的 WPF 应用程序,但无法绑定到组合框的 SelectedItem 属性。绑定属性的设置器没有被调用,并且调试窗口中没有输出告诉我它无法绑定(我假设它能够)。这是.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; }
}

打印机视图型号:

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());
}

谁能看到我在这里做错了什么?

4

2 回答 2

2

这里的问题是您对 Silverlight 依赖属性系统的工作方式存在误解。

当依赖属性的值发生变化时,Silverlight 不会通过您定义的属性(例如SelectedPrinter)来设置依赖属性的值。Silverlight 依赖属性机制会跟踪依赖属性的所有值,当这些属性之一的值发生更改时,Silverlight 会直接更改其值,而无需调用您的代码来执行此操作。特别是,它不会调用您的属性设置器。这应该可以解释为什么您的调试消息没有出现。

使用依赖属性的属性(例如您的SelectedPrinter属性)中的 getter 应仅包含对 的调用GetValue,而 setter 应仅包含对 的调用SetValue。您不应该向 getter 或 setter 添加任何代码,因为这样做不会达到您想要的效果。

此外,您正在视图模型层中使用依赖属性。这不是他们打算使用的地方。依赖属性仅用于视图层。您的视图模型类应该实现INotifyPropertyChanged而不是扩展DependencyObject.

可以将两个依赖属性绑定在一起。这是允许的,并且有时将视图层中的两个依赖属性连接在一起很有用。事实上,您示例中的绑定正在工作,这就解释了为什么您没有收到任何有关绑定问题的消息。

于 2012-07-20T12:17:10.767 回答
1

为什么在做 mvvm 时从 DependencyObject 继承?`

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

现在你的代码应该可以工作了

于 2012-07-20T10:39:39.027 回答