【问题标题】:How to implement INotifyPropertyChange (WPF, MVVM)如何实现 INotifyPropertyChange(WPF、MVVM)
【发布时间】:2018-04-18 10:22:13
【问题描述】:

当我在 ViewModel 中设置默认值时,它可以工作,但是当我更改任何内容时,视图保持不变......所以我认为这与 INotifyPropertyChanged 有关。 我花了大约 10 个小时“谷歌搜索”,但我无法找出问题所在。 所以这是我的代码,我希望你能告诉我有什么问题:)

我的观点:

<UserControl x:Class="Diplomarbeit.Views.TasteView" 
         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:Diplomarbeit"
         mc:Ignorable="d"
         >
<Grid>
    <Ellipse x:Name="Taste" Fill="{Binding FillColor, Mode=TwoWay}" Stroke="{Binding BorderColor, Mode=TwoWay}" StrokeThickness="10" Height="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" Margin="2,0,2,0"/>
    <Viewbox>
        <Label x:Name="TasteText" Content="{Binding Text, Mode=TwoWay}" Foreground="{Binding TextColor, Mode=TwoWay}" FontWeight="ExtraBold" VerticalAlignment="Center" HorizontalAlignment="Center"/>
    </Viewbox>
</Grid>

视图的代码隐藏:

    public partial class TasteView : UserControl
{
    public TasteView()
    {
        InitializeComponent();
        // DataContext der View auf ViewModel binden
        this.DataContext = new TasteViewModel();
    } 
}

我的视图模型:

public class TasteViewModel : INotifyPropertyChanged
{
    #region PropertyChanged-Event + Methode
    public event PropertyChangedEventHandler PropertyChanged; // Event wird deklariert

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); // Event wird gefeuert
        }
    }
    #endregion

    #region Felder
    //ID für Eindeutigkeit
    private int _iD;
    //Füllfarbe der Ellipse
    private SolidColorBrush _fillColor;
    //Randfarbe der Ellipse
    private SolidColorBrush _borderColor;
    //Text der im Label steht; ACHTUNG: Vor und nach der Zahl 2 Leerzeichen!
    private string _text;
    //Farbe des Texts im Label
    private SolidColorBrush _textColor;
    #endregion

    #region Eigenschaften

    //ID für Eindeutigkeit
    public int ID
    {
        get { return _iD; }
        set
        {
            if (value != _iD)
            {
                _iD = value;
                OnPropertyChanged("ID");
            }
        }
    }

    //Füllfarbe der Ellipse
    public SolidColorBrush FillColor
    {
        get { return _fillColor; }
        set
        {
            if (value != _fillColor)
            {
                _fillColor = value;
                OnPropertyChanged("FillColor");
            }
        }
    }

    //Randfarbe der Ellipse
    public SolidColorBrush BorderColor
    {
        get { return _borderColor; }
        set
        {
            if (value != _borderColor)
            {
                _borderColor = value;
                OnPropertyChanged("BorderColor");
            }
        }
    }

    //Text der im Label steht
    public string Text 
    {
        get { return _text; }
        set
        {
            if (value != _text)
            {
                _text = value;
                OnPropertyChanged("Text");
            }
        }
    }

    //Farbe des Texts im Label
    public SolidColorBrush TextColor 
    {
        get { return _textColor; }
        set
        {
            if (value != _textColor)
            {
                _textColor = value;
                OnPropertyChanged("TextColor");
            }
        }
    }
    #endregion     

    #region Konstruktoren

    //Farbige Taste mit Border, Text und ID ==> Vollständige Taste 
    public TasteViewModel(int iD, SolidColorBrush fillColor, SolidColorBrush borderColor, string text, SolidColorBrush textColor)
    {
        iD = ID;
        fillColor = FillColor;
        borderColor = BorderColor;
        text = Text;
        textColor = TextColor;
    }

    //Farbige Taste mit Border und ID, jedoch ohne Text
    public TasteViewModel(int iD, SolidColorBrush fillColor, SolidColorBrush borderColor)
    {
        iD = ID;
        fillColor = FillColor;
        borderColor = BorderColor;
    }

    //Leere Taste, allerdings mit ID
    public TasteViewModel(int iD)
    {
        iD = ID;
    }

    //Leere Taste
    public TasteViewModel()
    {

    }
    #endregion

【问题讨论】:

  • 一步:尝试查看[CallerMemberName]:参见:jesseliberty.com/2012/06/28/…
  • 另一个回避:为什么要在标签上使用 2way 绑定?
  • 您如何更改这些值?其余的似乎都井井有条。
  • 视图模型赋值给DataContext后如何设置值?我很确定您没有访问正确的视图模型实例。当然,标签的 Content 属性的双向绑定是没有意义的。
  • @David 现在您已经接受了一个答案(尽管很有用)并没有显示您实际问题的解决方案。你到底做错了什么,这将是一个秘密。什么是 SetMethod?

标签: c# wpf mvvm inotifypropertychanged


【解决方案1】:

为了提供信息,我打算将此模式与一些辅助属性一起使用。

public class ViewModel: INotifyPropertyChanged
{
    private string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            if (value == _text) return;
            _text= value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
 }

它应该可以工作。

...或者因为它被否决:也许不是。尽管如此。尝试使用助手。它可以保护您免受非强类型错字的影响。

【讨论】:

  • 就像你在评论中告诉我的那样,我没有 SetMethod。现在它可以工作了:)
【解决方案2】:

您在 TasteView.Xaml.cs 中设置了无效的构造函数。应该是这样的

public TasteView()
{
    InitializeComponent();
    // DataContext der View auf ViewModel binden
    this.DataContext = new TasteViewModel(1,Brushes.Red,Brushes.Green,"Taste",Brushes.Blue);
} 

那个构造函数应该如下所示。

public TasteViewModel(int iD, SolidColorBrush fillColor, SolidColorBrush borderColor, string text, SolidColorBrush textColor)
    {
        ID = iD;
        FillColor = fillColor;
        BorderColor = borderColor;
        Text = text;
        TextColor = textColor;
    }`

希望这对你有用。

【讨论】:

    【解决方案3】:

    你的构造器错了:

    //Farbige Taste mit Border, Text und ID ==> Vollständige Taste 
        public TasteViewModel(int iD, SolidColorBrush fillColor, SolidColorBrush borderColor, string text, SolidColorBrush textColor)
        {
            ID = iD;
            FillColor = fillColor ;
            BorderColor = borderColor;
            Text = text;
            TextColor = textColor;
        }
    

    其他两个也一样。

    编辑: 双向绑定是默认行为,无需在您的 xaml 中显式。

    如果您使用的是 c# 6 或更新版本,您应该使用 nameof() 运算符来表示 OnPropertyChanged()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 2015-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多