2017-09-26 78 views
2

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

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

一切都很好,我可以恰当地显示应该显示在我的StackPanel中的Foo项目。

我现在想添加一个复选框到标签为“Show all”的页面上,该页面将绑定到ViewModel上的一个属性。当它被选中时,我想显示所有的Foo项目,不管ShouldBeVisible说什么,并且如果没有按照ShouldBeVisible进行检查。

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

有没有办法更新基于运行时的可见性绑定我是否选中了我的复选框?

+1

上的VireModel了'ShowAll'绑定属性的变化,你能不通过迭代对象列表并将它们全部标记为“ShouldBeVisible”? – Lindsay

回答

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(); 
    } 
}