I am trying to use the IsHighlighted dependency property on the CustomView class. It works as expected when I pass it a hard bool value, but it doesnt work when I pass it a binding. Anyone know why?
Also should I be calling OnPropertyChanged in the IsHighlighted setter?
MainWindow.xaml
<StackPanel>
<!-- The data context is set properly -->
<TextBlock Text="{Binding Text}" FontSize="50"/>
<!-- This works! -->
<views:CustomView IsHighlighted="true"/>
<!-- This does not! -->
<views:CustomView IsHighlighted="{Binding Path=One}"/>
</StackPanel>
MainWindowViewModel.cs
public class MainWindowViewModel : ViewModelBase
{
private string _text;
public string Text
{
get { return _text; }
set { _text = value; }
}
private bool _one;
public bool One
{
get { return _one; }
set { _one = value; }
}
public MainWindowViewModel()
{
Text = "bound text!";
One = true;
}
}
CustomView.xaml
<UserControl>
<Grid Background="{Binding Path=CurrentBackground,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:CustomView}, AncestorLevel=1}}">
<TextBlock Text="{Binding IsHighlighted}" FontSize="40"/>
</Grid>
</UserControl>
CustomView.xaml.cs
public partial class CustomView : UserControl
{
public CustomView()
{
InitializeComponent();
DataContext = this;
}
public static readonly DependencyProperty IsHighlightedProperty =
DependencyProperty.Register(
name: "IsHighlighted",
propertyType: typeof(bool),
ownerType: typeof(CustomView)
);
public bool IsHighlighted
{
get => (bool)GetValue(IsHighlightedProperty);
set => SetValue(IsHighlightedProperty, value);
}
public Brush CurrentBackground
{
get
{
if (IsHighlighted)
return new SolidColorBrush(Colors.Yellow); // highlighted
else
return new SolidColorBrush(Colors.White); // not highlighted
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
First remove line DataContext = this;
. User control will inherit DataContext
from his parent (in this case MainWindow.xaml
and context will be MainViewModel
).
Another question is that you properly set DataContext to your MainWindow
. Did you set DataContext
of your MainWindow.xaml
like
this.DataContext = new MainWindowViewModel();
If not, do it somewhere in MainWindow.cs
(for example in constructor). The DataContext
property is the default source of your bindings.
Second thing is, you need to call PropertyChanged
in your MainWindowViewModel
One
property setter.
public bool One
{
get { return _one; }
set
{
_one = value;
OnPropertyChanged();
}
}
I am expecting that your ViewModelBase
is implementing the INotifyPropertyChanged
interface. If not you will need to implement it. In your case, it will work without the INotifyPropertyChanged
implementation because you set the One
property in constructor. But when you want to change this property in some logic in your ViewModel, you will need to notify the view that the One
property is changing/changed (you will do it with INotifyPropertyChanged` interface implementation).
One remark to these lines of code in Xaml.
<Grid Background="{Binding Path=CurrentBackground,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:CustomView}, AncestorLevel=1}}">
A better way how to change the background is to create a ValueConverter like.
public class BackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? new SolidColorBrush(Colors.Yellow) : SolidColorBrush(Colors.White);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Usage:
<Grid Background="{Binding IsHighlighted, Converter={StaticResource BackgroundConverter}}">
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.