In my program I would like to disable a contentPresenter
when my other contentPresenter
gets focus. Each presenter is represented by a property located in my MainWindowViewModel
. This is also where the IsEnabled
property is located for both presenters.
Both contentPresenters
are created with the following structure: UserControl -> ViewModel -> Data Model.
Right now I am trying to disable the necessary contentPresenter
by changing the IsEnabled
property in the main window's ViewModel from the code-behind of the contentPresenter
that gets focus.
contentPresenter
User Control code-behind:
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;
}
}
The line: ViewModel.MainViewModel.LeftWidgetEnabled = false;
successfully changes the property in the Main window's view model, but the view is not affected. Can I fix this by finding a way to call NotifyPropertyChange()
? If so, how would I do that?
If this is the completely wrong solution please let me know, and help me fix it.
Thank you
Update 1:
My complete base class:
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;
}
}
Update 2:
My LeftWidgetEnabled
property:
public bool LeftWidgetEnabled
{
get { return _leftWidgetEnabled; }
set { SetField(ref _leftWidgetEnabled, value, "LeftWidgetEnabled"); }
}
The LeftWidgetEnabled
of your ViewModel.MainViewModel
class must be like this:
private bool leftWidgetEnabled;
public bool LeftWidgetEnabled
{
get { return leftWidgetEnabled; }
set { SetField(ref leftWidgetEnabled, value, "LeftWidgetEnabled"); }
}
Also, your MainViewModel
must implement INotifyPropertyChanged .
You're better off letting the MainViewModel
inherit from a ViewModelBase
and let ViewModelBase
implement 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;
}
}
Update 1
Your ContentPresenter should then be bound like:
<ContentPresenter IsEnabled="{Binding Path=LeftWidgetEnabled}" />
while the DataContext
of your UserControl
(where the ContentPresenter
is on) should be an instance of MainViewModel
.
For instance:
<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>
You implement INotifyPropertyChanged as below
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.