wpf 使用 ViewModel 中的多态性绑定到 XAML 中带参数的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19980612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Binding to a method with parameter in XAML using polymorphism in ViewModel
提问by NZJames
I have a TabControl with six tabs in my ResultView. The ViewModel that sits behind this View can be either a ResultTypeOneViewModel or ResultTypeTwoViewModel, each of which derives from ResultViewModel but you can interchangeably use the result viewer with either result type.
我的 ResultView 中有一个带有六个选项卡的 TabControl。位于此视图后面的 ViewModel 可以是 ResultTypeOneViewModel 或 ResultTypeTwoViewModel,它们中的每一个都派生自 ResultViewModel,但您可以交替使用具有任一结果类型的结果查看器。
The difference is that in ResultTypeOneViewModel, tabs 1 & 3 need to be visible and the rest hidden. In ResultTypeTwoViewModel, tabs 2, 3, 4, 5, 6 need to be visible and tab 1 hidden.
不同之处在于,在 ResultTypeOneViewModel 中,选项卡 1 和 3 需要可见,其余部分需要隐藏。在 ResultTypeTwoViewModel 中,标签 2、3、4、5、6 需要可见,标签 1 需要隐藏。
I wanted to do this via something like
我想通过类似的东西来做到这一点
<TabItem Name="1" Visibility={Binding IsTabVisible(0)}>
<TabItem Name="2" Visibility={Binding IsTabVisible(1)}>
<TabItem Name="3" Visibility={Binding IsTabVisible(2)}>
etc...
And have an abstract method declaration in ResultsViewModel such as
并在 ResultsViewModel 中有一个抽象方法声明,例如
public abstract Visibility IsTabVisible(int index);
And in ResultsOneViewModel have
在 ResultsOneViewModel 中有
public override Visibility IsTabVisible(int index)
{
if (index == 0 || index == 2) return Visibility.Visible;
return Visibility.Hidden;
}
And in ResultsTwoViewModel have
在 ResultsTwoViewModel 中有
public override Visibility IsTabVisible(int index)
{
if (index == 0) return Visibility.Hidden;
return Visibility.Visible;
}
But I cannot figure out how to call a method like this with a parameter through bindings iN WPF XAML.
但是我无法弄清楚如何通过绑定 iN WPF XAML 使用参数调用这样的方法。
Can anyone suggest how I can do this or if it's not possible via this method, another way I could solve this problem?
任何人都可以建议我如何做到这一点,或者如果通过这种方法无法实现,我可以通过另一种方式解决这个问题?
回答by Sheridan
To answer your question directly, you can use the ObjectDataProvider
to call a method for you so you can work with the results:
要直接回答您的问题,您可以使用ObjectDataProvider
为您调用一个方法,以便您可以使用结果:
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:Windows="clr-namespace:System.Windows;assembly=PresentationCore"
...
<Window.Resources>
<ObjectDataProvider x:Key="IsTab1VisibleMethod"
ObjectType="{x:Type Windows:Visibility}" IsAsynchronous="True"
MethodName="IsTabVisible">
<ObjectDataProvider.MethodParameters>
<System:Int32>0</System:Int32>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
You should then be able to access the result like this (but you'd need one of these for each TabItem
):
然后,您应该能够像这样访问结果(但您需要为每个结果之一TabItem
):
<TabItem Visibility="{Binding Source={StaticResource IsTab1VisibleMethod}}" />
However, it's generally not good practice to manipulate UI properties such as Visibility
in code, so a better idea would be to use a BooleanToVisibilityConverter
to Bind
the Visibility
properties to bool
values as @Highcore suggested. You can see an example of this in the Binding a Button Visibility to bool value in ViewModelpost here on StackOverflow.
然而,这通常不是好的做法来操作UI特性,例如Visibility
代码,所以一个更好的主意是使用一个BooleanToVisibilityConverter
到Bind
的Visibility
属性bool
值@Highcore建议。您可以在 StackOverflow 上的在 ViewModel 中将按钮可见性绑定到 bool 值的帖子中看到这样的示例。
In my opinion, an even better solution would be to simply provide one view for every view model.
在我看来,更好的解决方案是简单地为每个视图模型提供一个视图。
回答by Enzojz
A better suggestion to this question is to use style.DataTrigger in style of TabItem like this:
这个问题的一个更好的建议是在 TabItem 的样式中使用 style.DataTrigger ,如下所示:
<TabItem>
<TabItem.Style>
<Style target="{x:Type TabItem}">
<Style.DataTriggers>
<DataTrigger Binding="{Binding IsTabVisible}" Value="False">
<Setter Property="Visibility" Value = "Collapsed"/>
</DataTrigger>
</Style.DataTrigers>
</Style>
<TabItem.Style>
</TabItem>
回答by XLars
You can use an indexer property to be able to pass a single parameter to a property. Although it's probably not very intuitive to return a boolean value from an indexer property it works fine for me. Also keep in mind the indexer property looses it's expected functionality.
您可以使用索引器属性将单个参数传递给属性。尽管从索引器属性返回布尔值可能不是很直观,但它对我来说很好用。还要记住,索引器属性失去了它的预期功能。
class MyClass
{
public bool this[int tabNumber]
{
get
{
// Do logic to determine visibility here or in a separate method
return IsTabVisible(tabNumber);
}
}
bool IsTabVisible(int tabNumber)
{
bool result;
// Method logic...
return result;
}
}
So in XAML you can use the class name and provide a parameter between square brackets.
因此,在 XAML 中,您可以使用类名并在方括号之间提供一个参数。
<TabItem Visibility="{Binding MyClass[0]}}"/>
If you need to raise a NotifyPropertyChanged for the indexer property use:
如果您需要为索引器属性引发 NotifyPropertyChanged,请使用:
NotifyPropertyChanged("Item[]");
I don't know if this fits into the MVVM pattern but it could be useful for anyone who wants to bind to a method with a single parameter.
我不知道这是否适合 MVVM 模式,但对于想要绑定到具有单个参数的方法的任何人来说,它可能很有用。