WPF PropertyMetadata не работает должным образом - PullRequest
0 голосов
/ 27 мая 2020

У меня ToggleSwitch UserControl. ToggleSwitch имеет DependencyProperty называется IsChecked, и это показывает статус проверки UserControl

ToggleSwitch.xaml.cs:

public bool IsChecked {
    get { return ( bool ) GetValue(IsCheckedProperty); }
    set { SetValue(IsCheckedProperty, value); }
}

public static readonly DependencyProperty IsCheckedProperty =
    DependencyProperty.Register("IsChecked", typeof(bool), typeof(ToggleSwitch), 
        new PropertyMetadata(false, IsCheckedPropertyOnChanged));


private static void IsCheckedPropertyOnChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
    if ( obj is ToggleSwitch ) {
        var res = ( ( ToggleSwitch ) obj );
        res.ChangeStatus();
    }
}

В то же время IsChecked статус может измениться, когда Происходит событие 'GridMouseLeftButtonDown' (пользователь щелкает ToggleSwitch):

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

Внешний вид изменяется с функцией ChangeStatus.

Код ниже показывает, как я привязываю IsChecked в MainWindow.xaml

<local:ToggleSwitch IsChecked="{Binding SelectedPerson.IsActive}"/>

SelectedPerson - это DependencyProperty в MainWindow.xaml.cs.

Свойство IsChecked успешно изменяется каждый раз, когда я создаю новый экземпляр SelectedPerson.

Но после срабатывания GridOnMouseLeftButtonDown (ToggleSwitch ClickEvent) IsCheckedPropertyOnChanged больше не вызывается.

Пример небольшого проекта, демонстрирующий проблему:

ToggleSwitch.xaml.cs:

public partial class ToggleSwitch : UserControl {


    public bool IsChecked {
        get { return ( bool ) GetValue(IsCheckedProperty); }
        set { SetValue(IsCheckedProperty, value); }
    }

    public static readonly DependencyProperty IsCheckedProperty =
        DependencyProperty.Register("IsChecked", typeof(bool), typeof(ToggleSwitch),
            new PropertyMetadata(false, IsCheckedPropertyOnChanged));
    private static void IsCheckedPropertyOnChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
        if ( obj is ToggleSwitch ) {
            var res = ( ( ToggleSwitch ) obj );
            res.ChangeStatus();
        }
    }

    public ToggleSwitch() {
        InitializeComponent();
    }

    private void ChangeStatus() {
        if ( IsChecked ) {
            MainContainer.Background = Brushes.Green;
        } else {
            MainContainer.Background = Brushes.Red;
        }
    }

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

ToggleSwitch.xaml:

<Grid MouseLeftButtonDown="GridOnMouseLeftButtonDown" Width="150" Height="150">
    <Border x:Name="MainContainer" Width="150" Height="150" BorderThickness="1" BorderBrush="Black" Background="White"/>
</Grid>

MainWindow.xaml.cs:

public class Person {
    public bool IsActive { get; set; }
}

public partial class MainWindow : Window {

    public Person SelectedPerson {
        get { return ( Person ) GetValue(SelectedPersonProperty); }
        set { SetValue(SelectedPersonProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SelectedPerson.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectedPersonProperty =
        DependencyProperty.Register("SelectedPerson", typeof(Person), typeof(MainWindow));



    public MainWindow() {
        InitializeComponent();
        this.DataContext = this;
        SelectedPerson = new Person {
            IsActive = true
        };
    }

    private void ButtonOnClicked(object sender, RoutedEventArgs e) {
        var change = !SelectedPerson.IsActive;
        SelectedPerson = new Person {
            IsActive = change
        };
    }
}

MainWindow.xaml:

<StackPanel Orientation="Vertical">
    <local:ToggleSwitch IsChecked="{Binding SelectedPerson.IsActive}" />
    <Button Content="ChangeItemSource" Click="ButtonOnClicked" Width="150" Margin="50" />
</StackPanel>
...