简体   繁体   English

StackPanel 的可见性(在 ItemsControl 内)可以由按钮控制吗?

[英]Can the Visibility of a StackPanel (inside an ItemsControl) be controlled by a button?

I have a property List<Filter> Filters which is the ItemSource of an ItemsControl .我有一个属性List<Filter> Filters ,它是ItemsControlItemSource What I am trying to accomplish is to show at the beginning only the filters which have the property IsShown = true .我想要完成的是在开始时只显示具有属性IsShown = true的过滤器。 Then, when I push the button, to show the rest of the filters.然后,当我按下按钮时,显示过滤器的 rest。 Is it possible to be done using XAML?是否可以使用 XAML 来完成? If no, which approach should I use?如果不是,我应该使用哪种方法?

The content of the Filter class is: Filter class的内容为:

        public List<string> Options { get; set; } = new List<string>();
        public bool IsShown { get; set; }
        public string Title { get; set; }
        public string ValueSelected { get; set; }

        public Filter(List<string> Options, string Title, string ValueSelected, bool IsShown)
        {
            this.Options = Options;
            this.Title = Title;
            this.ValueSelected = ValueSelected;
            this.IsShown = IsShown;
        }

In MainContext I have defined the List and a button:MainContext我定义了 List 和一个按钮:

        public ObservableCollection<Filter> Filters { get; set; } = new ObservableCollection<Filter>();
        public ICommand DoShowHide

In MainWindow.XAML at this point I have the following:MainWindow.XAML此时我有以下内容:

            <ItemsControl ItemsSource="{Binding Filters}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical" Visibility="{Binding Path=IsShown, Converter={StaticResource BoolToVisConverter} }" Name="MyStackPanel">
                            <TextBlock Text="{Binding Title}"/>
                            <ComboBox ItemsSource="{Binding Path=Options}"
                              SelectedValue="{Binding Path=ValueSelected}" />
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
            <Button Content="Show/Hide" Command="{Binding DoShowHide}"/>

with the mentioning that I have defined the converter提到我已经定义了转换器

<Window.Resources>
   <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</Window.Resources>

****I have tried to set all the filters' IsShown property to true at the push of the button. ****我试图在按下按钮时将所有过滤器的IsShown属性设置为 true。 No need to mention that it did not work...没用就不用说了...

        private void ShowHide(object obj)
        {
            MessageBox.Show("message");
            foreach(Filter filter in Filters)
            {
                if(filter.IsShown == false)
                {
                    filter.IsShown = true;
                    NotifyPropertyChanged("Filters");
                }
            }
        }

Thank you for taking the time to read my question:)感谢您花时间阅读我的问题:)

you can make it using converter where you return the a visibility object您可以使用转换器使其返回可见性 object

Your Filter class must implement INotifyPropertyChanged .您的Filter class 必须实现INotifyPropertyChanged Otherwise property changes inside this class are not propagated to the binding system.否则,此 class 内部的属性更改不会传播到绑定系统。

Raising the ProperyChanged event on the Filters property, as you did, is useless.正如您所做的那样,在Filters属性上ProperyChanged事件是没有用的。

Note: you can use XOR operation to toggle boolean values (show/hide).注意:您可以使用 XOR 操作来切换 boolean 值(显示/隐藏)。

Shortened Filter class:缩短Filter class:

class Filter : INotifyPropertyChanged
{       
  private bool isDisplayed
  public bool IsDisplayed
  {
    get => this.isDisplayed;
    set
    {
      if (value != this.isDisplayed)
      {
        this.isDisplayed = value;
        OnPropertyChanged();
      }
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;

  private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
  { 
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));        
  }
}

The shortened DataTemplate for the Filter item: Filter项的缩短的DataTemplate

<DataTemplate DataType="{x:Type Filter}">
  <StackPanel Visibility="{Binding IsDisplayed, Converter={StaticResource BoolToVisibilityConverter}}">

  </StackPanel>
</DataTemplate>

The modified ICommand execution handler:修改后的 ICommand 执行处理程序:

private void ShowHide(object obj)
{
  // Toggle all Filter.IsDisplayed
  foreach (Filter filter in Filters)
  {
    filter.IsDisplayed ^= true;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM