根据属性更改可见性绑定

时间:2017-09-26 15:26:31

标签: xaml uwp uwp-xaml

我的视图模型中有一个Foo对象列表。每个Foo对象都有一个属性ShouldBeVisible,它根据某个逻辑返回true或false,以确定是否应该向用户显示该项。

我创建了一个IValueConverter,它绑定到ShouldBeVisible属性以返回Visibility.Visible并折叠。

一切都很棒,我只能恰当地显示应该在我的StackPanel中显示的Foo项目。

我现在想在我的页面上添加一个复选框,标记为"显示所有",它将绑定到我的ViewModel上的属性。当它被检查时,我想要显示所有Foo项目,无论ShouldBeVisible说什么,以及是否未选中以跟随ShouldBeVisible。

我不确定如何正确绑定它,因为IValueConverter只能绑定到一个项目。

有没有办法在运行时根据我的复选框更新可见性绑定?

1 个答案:

答案 0 :(得分:0)

在WPF中,您可以使用IMultiValueConverter,但它不适用于UWP。在这种情况下,您可以使用Cimbalino Toolkit

在github上有一个具有此功能的示例:

https://github.com/Cimbalino/Cimbalino-Phone-Toolkit/tree/master/samples/MultiBinding/MultiBinding

在NuGet包中安装:Cimbalino.ToolkitMicrosoft.Xaml.Behaviors.Uwp.Managed

以下是一个简化示例。您应该在VisibilityConverter中验证传入的参数。

查看:

<Page
    x:Class="Q46430426.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Q46430426"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:behaviors="using:Cimbalino.Toolkit.Behaviors"
    mc:Ignorable="d"
    x:Name="page">
    <Page.Resources>
        <local:VisibilityConverter x:Key="VisibilityConverter" />
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <CheckBox IsChecked="{Binding ShowAll, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Content="ShowAll"></CheckBox>

        <ItemsControl Grid.Row="1" ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border Name="border" Margin="3" BorderThickness="2" BorderBrush="Black">
                        <interactivity:Interaction.Behaviors>
                            <behaviors:MultiBindingBehavior PropertyName="Visibility" Converter="{StaticResource VisibilityConverter}" >
                                <behaviors:MultiBindingItem Value="{Binding DataContext.ShouldBeVisible, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                                <behaviors:MultiBindingItem Value="{Binding DataContext.ShowAll, ElementName=page}"/>
                            </behaviors:MultiBindingBehavior>
                        </interactivity:Interaction.Behaviors>
                        <TextBlock Text="{Binding Name}"></TextBlock>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Page>

视图模型:

public class MainViewModel : ViewModelBase
{
    private bool _showAll;
    private ObservableCollection<Foo> _items;

    public MainViewModel()
    {
        Items = new ObservableCollection<Foo>()
    {
        new Foo(){Name = "Test1", ShouldBeVisible = true},
        new Foo(){Name = "Test2", ShouldBeVisible = false},
        new Foo(){Name = "Test3", ShouldBeVisible = true},
        new Foo(){Name = "Test4", ShouldBeVisible = false},
        new Foo(){Name = "Test5", ShouldBeVisible = true},
    };
    }

    public ObservableCollection<Foo> Items
    {
        get { return _items; }
        set { _items = value; RaisePropertyChanged(); }
    }

    public bool ShowAll
    {
        get { return _showAll; }
        set { _showAll = value; RaisePropertyChanged(); }
    }
}

VisibilityConverter:

public class VisibilityConverter : MultiValueConverterBase
{
    public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var shouldBeVisible = (bool)values[0];
        var showAll = (bool)values[1];
        if (showAll || shouldBeVisible) return Visibility.Visible;
        return Visibility.Collapsed;
    }

    public override object[] ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}