在不破坏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中如何拥有它,看起来它必须在后面的部分类代码中。
答案 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直接通信(通过属性/方法)。