WPF绑定会覆盖本地属性吗?

时间:2019-02-01 18:27:18

标签: c# wpf mvvm data-binding

我试图使用户控件根据选择的内容更改可见的内容。我遇到了这样一种情况:在绑定数据值之后,将不再触发用户控件中绑定到的本地属性的设置器。

我做了一个简单的例子,演示了我所看到的。

Window.xaml

<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">
    <Grid>
        <local:Picker HorizontalAlignment="Left" Margin="152,102,0,0" VerticalAlignment="Top" SelectedValue="{Binding Value}"/>
    </Grid>
</Window>

Picker.xaml

<UserControl
             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:WpfApp1" x:Class="WpfApp1.Picker"
             mc:Ignorable="d" Background="White" x:Name="uc">
    <StackPanel Orientation="Vertical" Width="100px">
        <ComboBox ItemsSource="{Binding ElementName=uc, Path=Values}" SelectedItem="{Binding ElementName=uc, Path=SelectedValue, UpdateSourceTrigger=PropertyChanged}"/>
        <CheckBox Visibility="{Binding ElementName=uc, Path=CheckVisibility}"/>
    </StackPanel>
</UserControl>

Picker.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for SchedulePicker.xaml
    /// </summary>
    public partial class Picker : UserControl
    {
        public static readonly DependencyProperty SelectedValueProperty = DependencyProperty.Register(nameof(SelectedValue), typeof(string), typeof(Picker), new FrameworkPropertyMetadata { BindsTwoWayByDefault = true });

        public Picker()
        {
            InitializeComponent();
        }

        public Visibility CheckVisibility { get; set; }

        public string SelectedValue
        {
            get => (string)GetValue(SelectedValueProperty);
            set
            {
                // this never fires
                SetValue(SelectedValueProperty, value);

                CheckVisibility = SelectedValue == "1" ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        public string[] Values
        {
            get => new string[]
                {
                    "1",
                    "2",
                    "3"
                };
        }
    }
}

MainWindowViewModel.cs

using System.ComponentModel;

namespace WpfApp1
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        private string _Value;

        public MainWindowViewModel()
        {
            Value = "1";
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public virtual string Value
        {
            get => _Value;
            set
            {
                // this fires properly
                _Value = value;

                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
            }
        }
    }
}

在示例中,MainWindowViewModel.cs Value属性完全按照我的期望触发了它的设置器;但是,Picker.xaml.cs SelectedValue属性的设置器永远不会触发。更改组合框值时,复选框的可见性不会改变。

绑定值时,它会使用绑定属性覆盖原始属性吗?如果是这样,我如何实现基于所选内容使控件可见的目标?我不喜欢在用户控件之外使用该逻辑的想法,因为就我而言,用户控件知道什么应该可见以及何时可见。

0 个答案:

没有答案