具有MVVM中的依赖项属性的用户控件

时间:2014-12-05 06:14:20

标签: wpf xaml mvvm user-controls

一个新手问题。谷歌搜索了几个小时后,我仍然无法得到 clean 的答案(#standarad)。

我有一个UserControl_1,它包含一个自定义控件和一个WPF控件。用户控件将用于其他WPF UserControl。

最后,我想在主要用户控件的XAML中执行此操作:

  XAML
      <i:UserControl_1  TargetDP = "{Binding SourceProperty, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" }" />

SourceProperty绑定到Main用户控件的DataContext,而TargetDP是UserControl_1中的依赖项属性。然后UserControl_1将此TargetDP向下/向上传递到其包含的控件。

那么我在哪里为用户控件放置DependencyProperty?

它似乎应该放在代码隐藏中,但我真的很想使用MVVM。

UserControl_1应该有自己的ViewModel与主用户控件分开,但是信息应该能够通过UserControl XAML绑定在主视图模型和用户控件视图模型之间传递(反之亦然)。

感谢您对此提供任何帮助或澄清。 (很抱歉,如果这看似重复,但其他文章似乎都没有指定在何处创建用户控件的新依赖项属性或如何实现此目的。)

1 个答案:

答案 0 :(得分:3)

以下是如何做到这一点(如果我理解正确的话!)。您有一个用户控件,称之为MyControl。创建MyControlView

<UserControl x:Class="Project.Controls.MyControlView"
             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" 
             mc:Ignorable="d">
    <Grid HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" 
                   Text="{Binding LabelText}" 
                   VerticalAlignment="Center"
                   HorizontalAlignment="Right"
                   Margin="5,0"/>
        <ComboBox Grid.Row="1" 
                  ItemsSource="{Binding ComboBoxItems}"
                  SelectedItem="{Binding SelectedItem}"
                  HorizontalAlignment="Stretch"
                  Margin="0,0,5,0"/>
    </Grid>
</UserControl>

现在视图模型将是

public class MyControlViewModel
{
    // Add the public properties for LabelText, ComboBoxItems and SelectedItem
    // and any other logic you require.
}

现在你感到困惑。如果我想在另一个视图中使用此控件,请将其命名为BigView我可以

<Window x:Class="NameSpace.BigView"
        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:Controls="clr-namespace:Project.Controls"> // Important reference to your control namespace.
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Controls:MyControlView Grid.Row="0" Margin="0,5" 
                                DataContext="{Binding MyControlA}"/>
        <Controls:MyControlView Grid.Row="1" Margin="0,5" 
                                DataContext="{Binding MyControlB}"/>
    </Grid>
</Window>

现在,在视图模型BigViewModel中,您将拥有两个属性

public RangeSliderControlViewModel MyControlA { get; set; }
public RangeSliderControlViewModel MyControlB { get; set; }

那么您可以通过MyControlA.LabelText = "Some Text"等访问每个控件属性。请注意,在BigViewModel MyControlA / MyControlB中不需要实现INotifyPropertyChanged,但您控制的属性必须才能冒泡的更新并更新BigView

我希望这会有所帮助。