3

私のプログラムでは、他の人がフォーカスを取得したcontentPresenterときにa を無効にしたいと考えています。contentPresenter各プレゼンターは、 my にあるプロパティによって表されますMainWindowViewModel。これはIsEnabled、両方のプレゼンターのプロパティが配置されている場所でもあります。

どちらcontentPresentersも次の構造で作成されます: UserControl -> ViewModel -> Data Model。

現在、メイン ウィンドウの ViewModel のプロパティを、フォーカスを取得するコード ビハインドからcontentPresenter変更して、必要なものを無効にしようとしています。IsEnabledcontentPresenter

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"); }
}
4

2 に答える 2

4

クラスのは次のようにする必要がありLeftWidgetEnabledます。ViewModel.MainViewModel

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

また、INotifyPropertyChangedMainViewModelを実装する必要があります。

MainViewModela から継承さViewModelBaseせ、 INotifyPropertyChangedViewModelBaseを実装させたほうがよいでしょう。

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}" />

DataContextあなたの(UserControlContentPresenterオンになっている) は のインスタンスである必要があります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>
于 2013-11-05T14:49:32.837 に答える