使用 WPF、MVVM 和 DP 的用户控件

UserControl using WPF, MVVM and DP

我正在尝试设计一个 UserControl,特别是一个 NumericUpDownControl。

<UserControl x:Class="SettingsDialog.Controls.NumericUpDownControl"
             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:SettingsDialog.Controls"
             xmlns:viewModels="clr-namespace:SettingsDialog.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="18"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding Value}" Grid.Row="0" Grid.RowSpan="2" Height="20" VerticalContentAlignment="Center"/>
        <RepeatButton Content="5" Grid.Column="1" Grid.Row="0" FontSize="8" Height="10" FontFamily="Marlett" VerticalContentAlignment="Center"/>
        <RepeatButton Content="6" Grid.Column="1" Grid.Row="1" FontSize="8" Height="10" FontFamily="Marlett"  VerticalContentAlignment="Center"/>
    </Grid>
</UserControl>

在 UserControl 的代码隐藏中,我有以下内容:

  public static readonly DependencyProperty ValueProperty =
     DependencyProperty.Register(
        "Value", typeof(int),
        typeof(NumericUpDownControl)
     );

  public int Value
  {
     get => (int)GetValue(ValueProperty);
     set => SetValue(ValueProperty, value);
  }

它工作正常,因为我可以像这样在我的 MainWindow.xaml 中使用它:

<controls:NumericUpDownControl Width="100" Value="10"/>

但问题是我还想为我的 UserControl 使用 ViewModel。当我设置它时,我的 UserControl 中的 TextBox 不再识别 Value 依赖项 属性。我怎样才能拥有一个 ViewModel 并同时从 UserControl 外部设置 Value?我做错了什么吗?

您不能同时将 UserControl 绑定到自身和 ViewModel。

您必须从 UserControl 中删除 DataContext="{Binding RelativeSource={RelativeSource Self}}",并确保在将它集成到您​​的 UI.

中时将正确的 DataContext 传递给 UserControl

这应该将 TextBoxText 属性 绑定到 UserControlValue 属性 而不管其 DataContext:

<TextBox Text="{Binding Value, RelativeSource={RelativeSource AncestorType=UserControl}}" Grid.Row="0" Grid.RowSpan="2" Height="20" VerticalContentAlignment="Center"/>

由于您正在制作一种自定义控件,另一种解决问题的方法是简单地使用 属性changed 依赖项的回调 属性,每次它发生变化时,您只需更新文本框的文字 属性:

    public partial class NumericUpDownControl : UserControl
    {
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(int),typeof(NumericUpDownControl),new PropertyMetadata(OnValueChanged));

        private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((NumericUpDownControl) d).TextBox.Text = e.NewValue?.ToString() ?? string.Empty;
        }

        public int Value
        {
            get => (int)GetValue(ValueProperty);
            set => SetValue(ValueProperty, value);
        }

        public NumericUpDownControl()
        {
            InitializeComponent();
        }
    }
}