将用户控件的子属性直接公开为用户控件的属性

本文关键字:控件 属性 用户 | 更新日期: 2023-09-27 17:56:48

在不破坏 MVVM 的情况下,有没有办法在用户控件中公开子控件的某些属性,以便使用它的窗口或其他用户控件可以直接访问这些属性?

例如,我有一个用户控件,该控件具有使用网格视图列,标题设置的列表视图,并绑定到视图模型。但是用户控件中的列表视图选择了项属性,因此我想向主机公开,而不必执行诸如usercontrol.customListView.property之类的操作。或者这就是我应该这样做的吗?我想只去usercontrol.property,省略customListView。也许我应该只在用户控件代码中创建属性,以返回我希望直接附加到用户控件的列表视图控件属性?

我觉得后一个选项并没有真正破坏 MVVM,因为它们是公开给主机交互的,与视图本身并不真正相关。任何建议将不胜感激。

编辑:事实上,我真的很想直接在用户控件上有一个 SelectedItem 属性,该属性不是 ListViewItem 或对象,但实际上包含的数据类型如下:

public MyDataType SelectedItem {
    get {
        return customListView.SelectedItem as MyDataType;
    }
}

这在 MVVM 中是允许的吗?因为我不明白我如何在 ViewModel 中拥有它,似乎它必须在后面的部分类代码中。

将用户控件的子属性直接公开为用户控件的属性

当您想将重复的内容放入UserControl时,这是很常见的任务。最简单的方法是,当您不是为该UserControl创建专用的 ViewModel 时,而是创建自定义控件(为简单起见,使用 UserControl 构建)。最终结果可能如下所示

<UserControl x:Class="SomeNamespace.SomeUserControl" ...>
    ...
    <TextBlock Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}" ...>
</UserControl>

.

public partial class SomeUserControl : UserControl
{
    // simple dependency property to bind to
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(SomeUserControl), new PropertyMetadata());
    // has some complicated logic
    public double Value
    {
        get { return (double)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(double), typeof(SomeUserControl),
        new PropertyMetadata((d, a) => ((SomeUserControl)d).ValueChanged()));
    private void ValueChanged()
    {
        ... // do something complicated here
            // e.g. create complicated dynamic animation
    }
    ...
}

用法在包含窗口中如下所示

<l:SomeUserControl Text="Text" Value="{Binding SomeValue}" ... />

如您所见,SomeValue绑定到Value并且没有 MVVM 违规。

当然,如果视图逻辑很复杂或需要太多绑定,则可以创建适当的ViewModel,并且允许 ViewModels 直接通信(通过属性/方法)更容易。