我有一个View MainWindow.xaml,它包含两个在Button.xaml中定义的按钮。该按钮绑定到属性IsVisible
,该属性定义按钮是否可见。
MainWindow.xaml:
<local:Button DataContext="{Binding ButtonViewModel1}" />
<local:Button DataContext="{Binding ButtonViewModel2}" />
Button.xaml:
<StackPanel>
<Button Name="MyButton" Visibility="{Binding IsVisible}">
<TextBlock>My Button</TextBlock>
</Button>
</StackPanel>
对于Button,我有两个ViewModel:ButtonViewModel
和ButtonViewModelChild
。
ButtonViewModelChild
继承自ButtonViewModel
。两者都提供IsVisible
属性:
ButtonViewModel:
public Visibility IsVisible
{
get
{
return Visibility.Hidden;
}
}
ButtonViewModelChild:
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();
}
}
如果ButtonViewModel
用作按钮的DataContext,则按钮应该是不可见的,如果使用ButtonViewModelChild
则可见。
我假设使用ButtonViewModel1作为DataContext的按钮获得ButtonViewModel
而另一个按钮获得ButtonViewModelChild
。所以第一个按钮不可见而第二个按钮会显示。这两个按钮都是可见的。 WPF在这做什么?显然,它使用了实例的继承视图。有没有办法告诉WPF使用属性的返回类型而不是创建实例类型?
我知道方法隐藏不是最好的做法。我可能会改变设计,但我很好奇为什么结果不如预期。
答案 0 :(得分:1)
绑定路径中的属性通过反射解析,因此无论ButtonViewModel1属性类型如何,它都会找到子类属性。
public ButtonViewModel ButtonViewModel1
{
get { return new ButtonViewModelChild(); } // subclass instance
}
为避免这种情况,您必须从getter返回ButtonViewModel
个实例:
public ButtonViewModel ButtonViewModel1
{
get { return new ButtonViewModel(); }
}
你也可以将属性声明为object
,绑定仍然有效:
public object ButtonViewModel1
{
get { return new ButtonViewModelChild(); }
}
除此之外,您通常不应让UserControl操作特定的视图模型(因此使其依赖于viel模型类)。相反,您应该在UserControl类中声明一个IsButtonVisible
依赖项属性,并绑定它,如下所示:
<StackPanel>
<Button Visibility="{Binding IsButtonVisible,
RelativeSource={RelativeSource AncestorType=UserControl}}">
<TextBlock>My Button</TextBlock>
</Button>
</StackPanel>
用法是:
<local:Button IsButtonVisible="{Binding ButtonViewModel1.IsVisible}" />
答案 1 :(得分:0)
我认为问题是getter中的类型错误,它们都返回ButtonViewModelChild viewmodel,当你从ButtonViewModel1而不是ButtonViewModelChild返回ButtonViewModel时它隐藏起来应该是