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

C# 直接将用户控件的子属性作为用户控件的属性公开,c#,wpf,mvvm,C#,Wpf,Mvvm,在不破坏MVVM的情况下,是否有方法公开用户控件中子控件的某些属性,以便使用它的窗口或其他用户控件可以直接访问这些属性 例如,我有一个用户控件,它的listview设置为gridviewcolumns、Header,并绑定到视图模型。但是用户控件中的列表视图选择了项属性,因此我希望向主机公开,而不必执行类似usercontrol.customListView.property的操作。还是我应该这样做?我只想使用usercontrol.property,忽略customListView。也许我应该

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


例如,我有一个用户控件,它的listview设置为gridviewcolumns、Header,并绑定到视图模型。但是用户控件中的列表视图选择了项属性,因此我希望向主机公开,而不必执行类似usercontrol.customListView.property的操作。还是我应该这样做?我只想使用usercontrol.property,忽略customListView。也许我应该在用户控件代码中创建属性,返回我想要直接附加到用户控件的列表视图控件属性

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

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

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

这在MVVM中是允许的吗?因为我不知道如何在ViewModel中使用它,似乎它必须在后面的部分类代码中。

当您想在
用户控件中重复某些内容时,这是一项非常常见的任务。最简单的方法是,当您不是为该
UserControl
创建专门的ViewModel时,而是创建某种自定义控件(为了简单起见,使用
UserControl
构建)。最终结果可能是这样的

<UserControl x:Class="SomeNamespace.SomeUserControl" ...>
    ...
    <TextBlock Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}" ...>
</UserControl>
在包含窗口中的用法如下所示

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

正如您所看到的,
SomeValue
绑定到
Value
并且没有MVVM冲突


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

只需在控件上添加DepandencyProperty并绑定到它/重新绑定它(
Binding RelativeSource{FindAncestor}
)在子控件上(顺便说一句,也可能是OT),WPF datagrid上的.columns不可绑定。MVVM没有任何问题-假设ComboBox正在使用其他控件,您在MVVM中使用它没有任何问题:)这个问题与MVVM无关。“我有一个用户控件,它的listview设置了gridviewcolumns、Header,并且绑定到视图模型。”是的,这就是您遇到问题的原因。用户控件中不应该有任何ViewModels。您应该为所需的一切公开曲面上的属性,然后将UC子控件绑定到这些属性。如果必须在UC中执行UI逻辑,请使用代码隐藏。不要创建设计用于UC内部的VM。TextBox是否具有TextBoxViewModel?不。把你的UC当作控制,而不是逻辑的子集。@Sheridan你读过问题了吗?我正在使用MVVM,希望在用户控件上公开一些内容。我不知道这是否会影响它的MVVM方面,或者我们是否应该在实践中避免这样做,但我只是不知道如何将这种暴露推迟到视图模型上。是的,我读了这个问题。你的设计对你不利。从你的第二次澄清来看,如果你的UC包含另一个不同的过程,它似乎太大了。UCs如果很小,则最有效,它被设计成一个专门的控件,专门针对整个MVVM设计的一部分进行设计(就像文本框编辑字符串一样,PersonUserControl可能编辑个人模型)。如果您使用UCs来包含大量的UI,您会发现自己处于上述注释中所述的情况中。视图本身存在自定义逻辑,这发生在视图模型中。例如,我正在处理的是一个具有公司数据类型的各种列的listview。我从Prism扩展BindableBase,通常使用SetProperty()来设置可能的属性。您知道SetProperty是否在尚未注册的情况下代表类自动注册DependencyProperty吗?我还想直接将SelectedItem作为公司类型公开,并为公司类型公开SelectionChanged事件。
<l:SomeUserControl Text="Text" Value="{Binding SomeValue}" ... />