C# 传递给UserControl的继承ViewModel被视为子ViewModel
我有一个视图MainWindow.xaml,其中包含在Button.xaml中定义的两个按钮。按钮绑定到一个属性C# 传递给UserControl的继承ViewModel被视为子ViewModel,c#,wpf,inheritance,method-hiding,C#,Wpf,Inheritance,Method Hiding,我有一个视图MainWindow.xaml,其中包含在Button.xaml中定义的两个按钮。按钮绑定到一个属性IsVisible,该属性定义按钮是否可见 MainWindow.xaml: <local:Button DataContext="{Binding ButtonViewModel1}" /> <local:Button DataContext="{Binding ButtonViewModel2}" /> 按钮查看模型儿童: public new Visib
IsVisible
,该属性定义按钮是否可见
MainWindow.xaml:
<local:Button DataContext="{Binding ButtonViewModel1}" />
<local:Button DataContext="{Binding ButtonViewModel2}" />
按钮查看模型儿童:
public new Visibility IsVisible
{
get
{
return Visibility.Visible;
}
}
MainWindow.xaml的ViewModel包含一个属性ButtonViewModel1
和ButtonViewModel2
。这些属性如下所示:
public ButtonViewModel ButtonViewModel1
{
get
{
return new ButtonViewModelChild();
}
}
public ButtonViewModelChildButtonViewModel2
{
get
{
return new ButtonViewModelChild();
}
}
<StackPanel>
<Button Visibility="{Binding IsButtonVisible,
RelativeSource={RelativeSource AncestorType=UserControl}}">
<TextBlock>My Button</TextBlock>
</Button>
</StackPanel>
如果按钮的数据上下文为ButtonViewModel
,则该按钮应不可见;如果使用ButtonViewModelChild
,则该按钮应可见
我假设使用ButtonViewModel1作为数据上下文的按钮得到一个ButtonViewModel
,另一个按钮得到一个ButtonViewModelChild
。因此,第一个按钮不可见,第二个按钮不可见。但两个按钮都是可见的。WPF在这里做什么?显然,它同时使用实例的继承视图。有没有办法告诉WPF使用属性的返回类型而不是创建的实例类型
我知道方法隐藏不是最佳实践。我可能会更改设计,但我很好奇为什么结果不符合预期。绑定路径中的属性是通过反射解析的,因此它会找到子类属性,而不管ButtonViewModel1属性类型如何
public ButtonViewModel ButtonViewModel1
{
get { return new ButtonViewModelChild(); } // subclass instance
}
为了避免这种情况,您必须从getter返回ButtonViewModel
实例:
public ButtonViewModel ButtonViewModel1
{
get { return new ButtonViewModel(); }
}
您也可以将属性声明为对象
,绑定仍然有效:
public object ButtonViewModel1
{
get { return new ButtonViewModelChild(); }
}
除此之外,通常不应让UserControl操作特定视图模型(从而使其依赖于viel模型类)。相反,您应该在UserControl类中声明一个
IsButtonVisible
dependency属性,并按如下方式绑定它:
public ButtonViewModel ButtonViewModel1
{
get
{
return new ButtonViewModelChild();
}
}
public ButtonViewModelChildButtonViewModel2
{
get
{
return new ButtonViewModelChild();
}
}
<StackPanel>
<Button Visibility="{Binding IsButtonVisible,
RelativeSource={RelativeSource AncestorType=UserControl}}">
<TextBlock>My Button</TextBlock>
</Button>
</StackPanel>
我的纽扣
用途如下:
<local:Button IsButtonVisible="{Binding ButtonViewModel1.IsVisible}" />
我认为问题是getter中的类型错误,它们都返回ButtonViewModelChildviewmodel,当您从ButtonViewModel1而不是ButtonViewModelChild返回ButtonViewModel时,它应该是隐藏的谢谢您的快速回答。那么两个按钮都不应该可见。但它们都是。您应该考虑到OP非常清楚这两个属性都返回一个子类实例。他们认为ButtonViewModel1属性的返回类型在某种程度上很重要。