簡體   English   中英

我是否需要在代碼隱藏中調用NotifyPropertyChange()?

[英]Do I need to call NotifyPropertyChange() in code-behind?

在我的程序中,我想在我的其他contentPresenter獲得焦點時禁用contentPresenter 每個演示者都由位於我的MainWindowViewModel的屬性表示。 這也是兩個演示者的IsEnabled屬性所在的位置。

兩個contentPresenters都使用以下結構創建:UserControl - > ViewModel - > Data Model。

現在我試圖通過從獲得焦點的contentPresenter的代碼隱藏更改主窗口的ViewModel中的IsEnabled屬性來禁用必要的contentPresenter

contentPresenter用戶控件代碼隱藏:

public partial class EditBlockUC : UserControl
{
    public EditBlockViewModel ViewModel { get { return DataContext as EditBlockViewModel; } }

    public EditBlockUC()
    {
        InitializeComponent();
    }

    //Runs when the user control gets focus
    private void UserControl_GotFocus(object sender, RoutedEventArgs e)
    {
        //This UserControl has access to MainWindowViewModel through
        //it's own ViewModel, EditBlockViewModel         
        ViewModel.MainViewModel.LeftWidgetEnabled = false;
    }
}

該行: ViewModel.MainViewModel.LeftWidgetEnabled = false; 在主窗口的視圖模型中成功更改屬性,但視圖不受影響。 我可以通過找到一種方法調用NotifyPropertyChange()來解決這個問題嗎? 如果是這樣,我該怎么做?

如果這是完全錯誤的解決方案,請告訴我,並幫我修復它。

謝謝

更新1:

我完整的基類:

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

    public virtual void NotifyPropertyChange<TProperty>(Expression<Func<TProperty>> property)
    {
        var lambda = (LambdaExpression)property;

        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = (UnaryExpression)lambda.Body;
            memberExpression = (MemberExpression)unaryExpression.Operand;
        }
        else
            memberExpression = (MemberExpression)lambda.Body;

        OnPropertyChanged(memberExpression.Member.Name);
    }

    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

更新2:

我的LeftWidgetEnabled屬性:

public bool LeftWidgetEnabled
{
    get { return _leftWidgetEnabled; }
    set { SetField(ref _leftWidgetEnabled, value, "LeftWidgetEnabled"); }
}

ViewModel.MainViewModel類的LeftWidgetEnabled必須如下所示:

private bool leftWidgetEnabled;
public bool LeftWidgetEnabled
{
    get { return leftWidgetEnabled; }
    set { SetField(ref leftWidgetEnabled, value, "LeftWidgetEnabled"); }
}

此外,您的MainViewModel必須實現INotifyPropertyChanged

你最好讓MainViewModelViewModelBase繼承,讓ViewModelBase實現INotifyPropertyChanged

public class MainViewModel : ViewModelBase
{        
    private bool leftWidgetEnabled;
    public bool LeftWidgetEnabled
    {
        get { return leftWidgetEnabled; }
        set { SetField(ref leftWidgetEnabled, value, "LeftWidgetEnabled"); }
    }
}

public class ViewModelBase : INotifyPropertyChanged
{
    // boiler-plate
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

更新1

然后,您的ContentPresenter應綁定如下:

<ContentPresenter IsEnabled="{Binding Path=LeftWidgetEnabled}" />

UserControlDataContextContentPresenter所在的位置)應該是MainViewModel一個實例。

例如:

<UserControl 
    x:Class="MyApplication.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:viewModels="**PATH TO YOUR VIEWMODELS-ASSEMBLY**"
    mc:Ignorable="d">

<UserControl.DataContext>
    <viewModels:MainViewModel />
</UserControl.DataContext>

    <ContentPresenter IsEnabled="{Binding Path=LeftWidgetEnabled}" />
</UserControl>

您實現INotifyPropertyChanged如下所示

class ViewModel : INotifyPropertyChanged
{

  private bool leftWidgetEnabled;
  public bool LeftWidgetEnabled
  {
     get 
      { 
        return leftWidgetEnabled;
      }
      set 
      { 
          leftWidgetEnabled=value
         OnPropertyChanged("LeftWidgetEnabled"); 
      }
   }

    public void OnPropertyChanged(string PropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM