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

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

ここで私が間違っていることを誰かが見ることができますか?

4

2 に答える 2

2

ここでの問題は、Silverlight の依存関係プロパティ システムがどのように機能するかについて誤解していることです。

依存関係プロパティの値が変更された場合、Silverlight は依存関係プロパティの値を設定するために定義したプロパティ ( など) を調べませんSelectedPrinter。Silverlight の依存関係プロパティ メカニズムは、依存関係プロパティのすべての値を追跡します。これらのプロパティのいずれかの値が変更されると、Silverlight はその値をコードを呼び出すことなく直接変更します。特に、プロパティ セッターは呼び出されません。これにより、デバッグ メッセージが表示されなかった理由が説明されます。

プロパティなど、依存関係プロパティを使用するプロパティの getter にはSelectedPrinterへの呼び出しのみをGetValue含める必要があり、setter には への呼び出しのみを含める必要がありますSetValue。ゲッターまたはセッターにコードを追加しないでください。これを行うと、目的が達成されません。

さらに、ビュー モデル レイヤーで依存関係プロパティを使用しています。これは、それらが使用されることを意図した場所ではありません。依存関係プロパティは、view-layer でのみ使用することを意図しています。ビューモデル クラスは、 を拡張するのではなく、実装するINotifyPropertyChangedDependencyObject必要があります。

2 つの依存関係プロパティを一緒にバインドすることができます。これは許可されており、view-layer で 2 つの依存関係プロパティを結び付けると便利な場合があります。実際、あなたの例のバインディングは機能していました。これは、バインディングの問題に関するメッセージが表示されなかった理由を説明しています。

于 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 に答える