Binding to a method with parameter in XAML using polymorphism in ViewModel

泄露秘密 提交于 2019-12-21 07:37:01

问题


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.

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.

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

public abstract Visibility IsTabVisible(int index);

And in ResultsOneViewModel have

public override Visibility IsTabVisible(int index)
{
    if (index == 0 || index == 2) return Visibility.Visible;
    return Visibility.Hidden;
}

And in ResultsTwoViewModel have

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.

Can anyone suggest how I can do this or if it's not possible via this method, another way I could solve this problem?


回答1:


To answer your question directly, you can use the ObjectDataProvider to call a method for you so you can work with the results:

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 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 ViewModel post here on StackOverflow.

In my opinion, an even better solution would be to simply provide one view for every view model.




回答2:


A better suggestion to this question is to use style.DataTrigger in style of TabItem like this:

<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>


来源:https://stackoverflow.com/questions/19980612/binding-to-a-method-with-parameter-in-xaml-using-polymorphism-in-viewmodel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!