从父元素到子元素的 WPF 绑定

本文关键字:元素 WPF 绑定 | 更新日期: 2023-09-27 18:36:09

这是我的 XAML

 <ListView x:Name="missingVariablesListView" ScrollViewer.CanContentScroll="True" HorizontalAlignment="Left" Height="320" Margin="81,28,0,0" VerticalAlignment="Top" Width="641" ItemsSource="{Binding}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="ComponentID: " FontWeight="Bold" Foreground="Brown" />
                                <TextBlock Text="{Binding Name}"/>
                            </StackPanel>
                            <ItemsControl ItemsSource="{Binding Parameters}">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel>
                                            <StackPanel Orientation="Horizontal">
                                                <TextBlock Text="Variable Name: " Foreground="Green"/>
                                                <TextBlock Text="{Binding Name}"/>
                                                <TextBlock Text="   "/>                                           
                                                <TextBlock Text="Variable Value: " Foreground="Blue"/>
                                                <TextBlock Text="{Binding Value}"/>
                                            </StackPanel>
                                        </StackPanel>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                                <ItemsControl.ItemContainerStyle>
                                    <Style >
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding IsMissing}" Value="false">
                                                <Setter Property="UIElement.Visibility" Value="Collapsed"/>                                                    
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </ItemsControl.ItemContainerStyle>
                            </ItemsControl>                           
                                <TextBlock Text="-----------------------------------------------------------------"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

这是代码隐藏

  this.missingVariablesListView.DataContext = //Code to fill in the list View

涉及的类

public class Component
  {
  private ObservableCollection<ComponentParameter> parameters = new ObservableCollection<ComponentParameter>();
  public string Name
  {
    get;
    set;
  }
  public ObservableCollection<ComponentParameter> Parameters
  {
    get{return parameters;}
    set{parameters = value;}
   }
}

 public class ComponentParameter
 {
   public string Name
   {
    get;set;
   }
    public string Value
   {
    get;set;
   }
   public bool HasErrors
   {
    get;
    set;
   }
   public bool IsMissing
   {
    get;set;
   }

样本输出(目前)

ComponentID: Component1
--------------------------
ComponentID: Component2
VariableName:Var1 Variable Value:Val1
VariableName:Var2 Variable Value:Val2
-----------------------
ComponentID: Component3
-----------------------
ComponentID: Component4
-----------------------

我想做的是,每当布尔值 IsMissing 对于 itemsControl 中的内部元素为真时,我都想确保 StackPanel 中的 ComponentID 和 Name 属性(方向为水平)不会显示在包括子元素在内的窗口中。基本上,我正在尝试找到一种方法来排除该特定组件ID的整个描述,该组件ID的isMissing 变量设置为true。对此有什么建议吗?

从父元素到子元素的 WPF 绑定

我会考虑向Component类添加一个属性IsAnyParameterMissing

public class Component
{
    private ObservableCollection<ComponentParameter> parameters = new ObservableCollection<ComponentParameter>();
    public string Name
    {
      get;
      set;
    }
    public ObservableCollection<ComponentParameter> Parameters
    {
        get{return parameters;}
        set{parameters = value;}
    }
    public bool IsAnyParameterMissing
    {
        get { return this.Parameters.Any(param => param.IsMissing); }
    }
}

然后将可见性绑定到此属性:

<StackPanel Orientation="Horizontal" Visibility="{Binding IsAnyParameterMissing, Converter={BooleanToVisibilityConverter}}">
    <TextBlock Text="ComponentID: " FontWeight="Bold" Foreground="Brown" />
    <TextBlock Text="{Binding Name}"/>
</StackPanel>

当集合中的任何 ParameterIsMissing 属性等于 true 时,这将仅显示StackPanel。请注意,如果更改了任何项目的 IsMissing 属性,这不会更改可见性!这需要一些额外的工作。

编辑:请注意,{BooleanToVisibilityConverter}可能需要调整,具体取决于可用的转换器。不过应该是一个简单的任务。

我注意到的一件事是你没有将属性(例如"isMissing")实现为依赖属性。您也不通过 INotifyPropertyChange 使用属性更改通知。

您必须实现两者中的任何一个,否则属性的更改将不会通过绑定传播。这意味着,触发器不会触发...

您可以使用

BooleanToVisibilityConverter来隐藏这些项目,但您可能需要为此更改属性或添加新的IsPresent属性

Resources

<Converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" 
    IsInverted="True" />

在您的ListView.ItemTemplate

<StackPanel Orientation="Horizontal" Visibility="{Binding IsMissing, Converter={
    StaticResource BoolToVisibilityConverter}}">
    <TextBlock Text="ComponentID: " FontWeight="Bold" Foreground="Brown" />
    <TextBlock Text="{Binding Name}"/>
</StackPanel>

具有IsInverted属性的自定义BoolToVisibilityConverter

[ValueConversion(typeof(bool), typeof(Visibility))]
public class BoolToVisibilityConverter : IValueConverter
{
    public bool IsInverted { get; set; }
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || value.GetType() != typeof(bool)) return null;
        bool boolValue = IsInverted ? !(bool)value : (bool)value;
        return boolValue ? Visibility.Visible : Visibility.Collapsed;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || value.GetType() != typeof(Visibility)) return null;
        if (IsInverted) return (Visibility)value != Visibility.Visible;
        return (Visibility)value == Visibility.Visible;
    }
}

现在只需一分钟即可实现它。我已经更新了上面的 XAML 示例以使用它。