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

时间:2015-06-18 07:13:21

标签: c# wpf mvvm

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

例如,我有一个用户控件,其中listview设置了gridviewcolumns,headers,并绑定到视图模型。但是用户控件中的列表视图选择了项属性,这样我就可以向主机公开,而不必像usercontrol.customListView.property那样做。或者我应该怎么做呢?我想去usercontrol.property,省略customListView。 Perhap我应该在后面的用户控件代码中创建属性,返回列表视图控制我想直接附加到用户控件的属性?

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

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

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

MVVM中允许这样做吗?因为我没有看到我在ViewModel中如何拥有它,看起来它必须在后面的部分类代码中。

1 个答案:

答案 0 :(得分:2)

当您想要将重复内容放入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,并且允许ViewModel直接通信(通过属性/方法)。