PropertyChanged 和 IValueConverter
PropertyChanged and IValueConverter
我需要在单击 TextBlock 中的 UserControl 时根据 IsChecked 的值更改可见性
我想制作我的复选框,但我 运行 遇到了这样的问题。
System.NullReferenceException: "The object reference does not point to an instance of the object." 在 OnPropertyChanged 方法中。
此控件的逻辑是,当您在其上单击 Visibility 时,TextBlock 应该变为 Hidden 或 Visible(取决于 IsChecked 值)。
如果我不写OnPropertyChanged("IsChecked");然后当点击没有崩溃,但没有任何反应时。
UserCheckBox.xaml.cs
public partial class UserCheckBox : UserControl
{
public UserCheckBox()
{
InitializeComponent();
DataContext = this;
MouseUp += delegate (object sender, MouseButtonEventArgs e)
{
this.IsChecked = true;
};
}
private bool _IsChecked = false;
public bool IsChecked
{
get { return _IsChecked; } private set { _IsChecked = value; OnPropertyChanged("IsChecked"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
UserCheckBox.xaml
<UserControl x:Class="COP.UserCheckBox"
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:COP"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="30" Background="#707070" Name="mainCheckBox">
<UserControl.Resources>
<local:VisibilityConvert x:Key="Convert"></local:VisibilityConvert>
</UserControl.Resources>
<Border BorderThickness="2" BorderBrush="Black">
<Grid>
<TextBlock FontFamily="Segoe UI Symbol" Text="" Visibility="{Binding ElementName=mainCheckBox, Path=IsChecked, Converter={StaticResource Convert}}"></TextBlock>
</Grid>
</Border>
VisibilityConvert.cs
class VisibilityConvert : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value == true ? Visibility.Visible : Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
你的 UserControl 必须使用 INotifyPropertyChanged
接口,否则 WPF 不知道要听这个 class.
这样做:
public partial class UserCheckBox : UserControl, INotifyPropertyChanged
此外,您的 IsChecked setter 是私有的,而它应该是 public,否则您无法设置 属性。
另一件需要注意的事情是,你不能在这个 属性 上使用 Binding
因为它不是依赖项 属性 所以你只能在 [=41= 中设置它] 这样 IsChecked="True"
。您可能想创建一个依赖关系 属性,阅读 this article.
编辑:
由于我在测试您的代码 OP 时设置了 IsChecked="True",我忘记了您还需要订阅鼠标左键单击事件,请在您的 UserControl 上执行此操作 XAML:
MouseLeftButtonDown="OnMouseLeftButtonDown" Background="Transparent"
然后在 UserControl.xaml.cs 中创建方法:
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
IsChecked = !IsChecked;
}
透明背景的原因是为了在 UserControl 的整个区域启用点击事件。
综上所述,我强烈建议您放弃这整件事。学习如何设置现有 Checkbox 控件的样式比创建自己的控件要好得多。
我需要在单击 TextBlock 中的 UserControl 时根据 IsChecked 的值更改可见性
我想制作我的复选框,但我 运行 遇到了这样的问题。 System.NullReferenceException: "The object reference does not point to an instance of the object." 在 OnPropertyChanged 方法中。 此控件的逻辑是,当您在其上单击 Visibility 时,TextBlock 应该变为 Hidden 或 Visible(取决于 IsChecked 值)。 如果我不写OnPropertyChanged("IsChecked");然后当点击没有崩溃,但没有任何反应时。
UserCheckBox.xaml.cs
public partial class UserCheckBox : UserControl
{
public UserCheckBox()
{
InitializeComponent();
DataContext = this;
MouseUp += delegate (object sender, MouseButtonEventArgs e)
{
this.IsChecked = true;
};
}
private bool _IsChecked = false;
public bool IsChecked
{
get { return _IsChecked; } private set { _IsChecked = value; OnPropertyChanged("IsChecked"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
UserCheckBox.xaml
<UserControl x:Class="COP.UserCheckBox"
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:COP"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="30" Background="#707070" Name="mainCheckBox">
<UserControl.Resources>
<local:VisibilityConvert x:Key="Convert"></local:VisibilityConvert>
</UserControl.Resources>
<Border BorderThickness="2" BorderBrush="Black">
<Grid>
<TextBlock FontFamily="Segoe UI Symbol" Text="" Visibility="{Binding ElementName=mainCheckBox, Path=IsChecked, Converter={StaticResource Convert}}"></TextBlock>
</Grid>
</Border>
VisibilityConvert.cs
class VisibilityConvert : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value == true ? Visibility.Visible : Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
你的 UserControl 必须使用 INotifyPropertyChanged
接口,否则 WPF 不知道要听这个 class.
这样做:
public partial class UserCheckBox : UserControl, INotifyPropertyChanged
此外,您的 IsChecked setter 是私有的,而它应该是 public,否则您无法设置 属性。
另一件需要注意的事情是,你不能在这个 属性 上使用 Binding
因为它不是依赖项 属性 所以你只能在 [=41= 中设置它] 这样 IsChecked="True"
。您可能想创建一个依赖关系 属性,阅读 this article.
编辑:
由于我在测试您的代码 OP 时设置了 IsChecked="True",我忘记了您还需要订阅鼠标左键单击事件,请在您的 UserControl 上执行此操作 XAML:
MouseLeftButtonDown="OnMouseLeftButtonDown" Background="Transparent"
然后在 UserControl.xaml.cs 中创建方法:
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
IsChecked = !IsChecked;
}
透明背景的原因是为了在 UserControl 的整个区域启用点击事件。
综上所述,我强烈建议您放弃这整件事。学习如何设置现有 Checkbox 控件的样式比创建自己的控件要好得多。