Как добавить элементу CheckBox к событию checked обработчик события не через двойного клика WPF?

Помогите начинающему советом где и как искать. Проект WPF состоит из MainWindow.xaml, в котором разметка и отдельно класс ViewModel.cs, в котором прописаны свойства которые биндятся к форме.

На форме есть елемент

<CheckBox 
   Name="CB_IsTreeView"
   Content="CheckBox" 
   HorizontalAlignment="Left" 
   Margin="303,45,0,0" 
   VerticalAlignment="Top" 
   Checked="?????"  
/>

Пытаюсь добавить событие Checked обработчик на метод в классе ViewModel.

public void CheckBox_Checked(object sender, RoutedEventArgs e)
{
}

Хочу обратить внимание что MainWindow.xaml и ViewModel.cs связаны только через Binding.

<Window x:Class="WpfApp1.MainWindow"
        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:local="clr-namespace:WpfApp1"  
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>

Вопрос: как связать событие Checked с методом CheckBox_Checked без использавания MainWindow.xaml.cs?


Ответы (1 шт):

Автор решения: aepot

Checked - это не свойство, это событие, а свойство - это IsChecked.

В MVVM это делается примерно так. Обработчик не нужен (совсем).

public class NotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public class ViewModel : NotifyPropertyChanged
{
    private bool _treeViewChecked;

    public bool TreeViewChecked
    {
        get => _treeViewChecked;
        set
        {
            _treeViewChecked = value;
            OnPropertyChanged();
            // сюда можно добавить свой код, только осторожно,
            // код не должен выполняться долго
            OnTreeViewChecked();
        }
    }

    private void OnTreeViewChecked()
    {
        // Использовать MessageBox в ViewModel - плохая практика, но работать будет, показываю для наглядности.
        MessageBox.Show("Новое значение чекбокса: " + TreeViewChecked);
    }

    // ... ваш код
}

Нужно назначить не событие, а привязать свойство. Вот это Name="CB_IsTreeView" больше не нужно, уберите его.

<CheckBox 
   Content="CheckBox" 
   HorizontalAlignment="Left" 
   Margin="303,45,0,0" 
   VerticalAlignment="Top" 
   IsChecked="{Binding TreeViewChecked}"  
/>

При этом теперь вы можете поставить или снять галку даже програмно из ViewModel.

TreeViewChecked = true;

Так же к этому же свойству можно прибиндить любой другой контрол, если например вам нужно задать чекбоксом видимость TreeView, то можно сделать это в стиле.

<TreeView ...>
    <TreeView.Style>
        <Style TargetType="TreeView">
            <Setter Property="IsVisible" Value="Visible"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding TreeViewChecked}" Value="False">
                    <Setter Property="IsVisible" Value="Collapsed"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TreeView.Style>
</TreeView>
→ Ссылка