0

現在、C# 4 で MVVM に従おうとしていますが、バインディングの動作に問題があります。

下から順に、XAML バインディング用に変更されたプロパティを処理する必要がある私の Property クラスを次に示します。

namespace Visualizer.MVVM
{
    public class Property<T> : DependencyObject, INotifyPropertyChanged
    {
        //private T _Value;
        public T Value
        {
            get { return (T) GetValue(ValueProperty); }
            set
            {
                SetValue(ValueProperty, value);
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged()
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("Value"));
            }
        }

        public Property(T val)
        {
            Value = val;
        }

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(T), typeof(Property<T>));
    }
}

コントロールの ViewModel は次のようになり、MainWindow.xaml.cs でインスタンス化されます。

public class CheckboxControlVM
{
    public Property<bool> IsChecked { get; set; }
    public Property<string> Name { get; set; }

    public CheckboxControlVM(bool isChecked, string name)
    {
        IsChecked = new Property<bool>(isChecked);
        Name = new Property<string>(name);
    }
}

コントロールにはコード ビハインドがないため、その XAML は次のとおりです。

<UserControl x:Class="Visualizer.MVVM.Checkbox"
             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"
             xmlns:local="clr-namespace:Visualizer.MVVM"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Orientation="Horizontal" x:Name="LayoutRoot">
        <CheckBox IsChecked="{Binding Path=IsChecked.Value, Mode=TwoWay}"/>
        <TextBlock Text="{Binding Path=Name.Value, Mode=OneWay}"/>
    </StackPanel>
</UserControl>

最後に、MainWindow.xaml のバインディングを次に示します。

<mvvm:Checkbox DataContext="{Binding Realtime}"/>

私はこれに本来あるべきよりもずっと長い間立ち往生しており、単純な問題であるとかなり確信しています. 何か案は?

4

2 に答える 2

1

そのプロパティの設計で達成したい目的がよくわかりません。通常、私はWPFでそれをしないので、これが役立つかどうかはよくわかりません.

通常、VM が所有する属性ではなく、ViewModel レベルで INotifyPropertyChanged を実装します。例:

public class ViewModel : INotifyPropertyChanged{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

次に、WPF ユーザー コントロールを作成しない限り、DependencyProperty を使用しません。そのため、プライベート プロパティを使用し、プロパティ名で OnPropertyChanged をトリガーします。

private string _name;
public string Name{
  set{
    _name = value;
    OnPropertyChanged("Name");
  }
}

最後に、XAML では、UpdateSourceTrigger=PropertyChanged でバインディングを使用します。

<TextBlock Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

UpdateSourceTrigger=PropertyChangedバインディングを追加してみることができるかもしれませんが、うまくいくかどうかはわかりません。

于 2013-04-04T05:14:49.230 に答える
0

これを試して

public class CheckboxControlVM
  {
    bool _isChecked = false;
    string _name ;
  public Property<bool> IsChecked { get { return _isChecked} set { _isChecked=value;} }

  public Property<string> Name { get { return _name } set { _name =value;} }

  public CheckboxControlVM(bool isChecked, string name)
  {
    _isChecked = isChecked;
     _name = name;
    IsChecked = new Property<bool>(_isChecked);
    Name = new Property<string>(_name);
  }
}
于 2013-04-04T04:52:12.377 に答える