PropertyChanged и IValueConverter

Мне нужно, чтобы при нажатии на UserControl в TextBlock видимость менялась в зависимости от того, какое значение IsChecked

Я хотел сделать свой флажок, но столкнулся с такой проблемой. System.NullReferenceException: "Ссылка на объект не указывает на экземпляр объекта". в методе OnPropertyChanged. Логика этого элемента управления заключается в том, что при нажатии на него "Видимость" TextBlock должен стать скрытым или видимым (зависит от значения 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="&#xE10B;" 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();
    }
}

1 ответ

Решение

Ваш UserControl должен использовать INotifyPropertyChanged интерфейс, иначе WPF не знает, чтобы слушать этот класс.

Сделай это:

public partial class UserCheckBox : UserControl, INotifyPropertyChanged

Кроме того, ваш установщик IsChecked является закрытым, если он должен быть публичным, иначе вы не сможете установить свойство.

Еще одна вещь, которую стоит отметить, это то, что вы не можете использовать Binding на это свойство, потому что это не свойство зависимости, поэтому вы можете установить его только в XAML, как IsChecked="True", Возможно, вы захотите создать свойство зависимости, прочитайте эту статью.

РЕДАКТИРОВАТЬ:

Так как у меня было IsChecked="True" при тестировании вашего кода OP, я забыл, что вам также нужно подписаться на событие щелчка левой кнопкой мыши, сделайте это на вашем UserControl XAML:

MouseLeftButtonDown="OnMouseLeftButtonDown" Background="Transparent"

Затем создайте метод в вашем UserControl.xaml.cs:

private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    IsChecked = !IsChecked;
}

Причиной появления прозрачного фона является включение событий щелчка во всей области UserControl.

Все это, как говорится, я настоятельно рекомендую вам отказаться от всего этого. Вы гораздо лучше научитесь стилизовать существующий элемент управления Checkbox, чем создавать свой собственный.

Другие вопросы по тегам