将 StackPanel 的 Visibility 属性绑定到其子元素的 Visibility 属性。

4

我是DataBinding的新手,正在学习相关知识。我想要做的事情是:

我有一个StackPanel,其中包含多个子控件:

        <StackPanel Orientation="Horizontal">
            <TextBox x:Name="textbox1" Width="100">1</TextBox>
            <TextBox x:Name="textbox2" Width="100">2</TextBox>
            <TextBox x:Name="textbox3" Width="100">3</TextBox>
        </StackPanel>

文本框的visibility属性可以通过代码更改。如果所有TextBoxe都设置为Visibility=Collapsed,我也希望StackPanel.Visibility设置为Collapsed,但是如果有一个或多个TextBoxe显示出来 (Visibility=Visible)StackPanel.Visibility也应该设置为Visible。这个功能能够通过简单的数据绑定实现吗?还是需要在C#代码中实现?
2个回答

7
我无法直接通过数据绑定来完成这个任务。个人建议是在视图后面加上一个视图模型,然后将视图的DataContext设置为视图模型。在视图模型中,我会设置一个属性来告诉视图所有文本框是否都被折叠起来了,并且这个属性是由代码设置的。然后将StackPanel的可见性绑定到该属性。(该属性必须是依赖属性,或者视图模型必须实现INotifyPropertyChanged接口,以便视图可以自动更新)。

5
您是否考虑将TextBox的可见性设置为“隐藏”?这将“隐藏”为TextBox分配的空间。假设StackPanel中没有其他控件,那么它将不可见。
当然,这个解决方案可能对您的实现做出了一些天真的假设。
如果您需要更复杂的情况,则可以尝试以下操作: 注意:这是伪代码 - 可能无法编译。
1)使用MultiBinding
<StackPanel>
  <StackPanel.Visibility Converter={StaticResource visibilityConverter}>
    <MultiBinding.Bindings>
      <Binding ElementName="textBox1" Path="Visibility" />
      <Binding ElementName="textBox2" Path="Visibility" />
      <Binding ElementName="textBox3" Path="Visibility" />
    </MultiBinding.Bindings>
  </StackPanel.Visibility>
</StackPanel>

2) 声明转换器

<Window.Resources>
  <local:VisibilityConverter x:Key="visibilityConverter" />
</Window.Resources>

3) 定义转换器

public class VisibilityConverter : IMultiValueConverter
{
  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  {
    Visibility text1Vis = (Visibility)values[0];
    Visibility text2Vis = (Visibility)values[1];
    Visibility text3Vis = (Visibility)values[2];

    if (text1Vis == text2Vis == text3Vis == Visibility.Collapsed)
      return Visibility.Collapsed;

    return Visibility.Visible;
  }
}

2
小错误:Converter={StaticResource visibilityConverter} 应该放在 MultiBinding.Bindings 而不是 Visibility。 - Greg R
1
XAML中的语法错误。转换器放在MultiBinding元素上。将<MultiBinding.Bindings>更改为<MultiBinding>。(您可以在上面没有父元素的情况下使用属性元素语法)。在发布代码之前需要编译代码。 - Sean Sexton
@SeanSexton,我在我的回答中提到了我正在提供伪代码。实际上,我是在原始问题发布后9分钟发布的,所以我没有机会运行完整的项目并测试代码。这个网站的美妙之处在于你可以随时编辑我的回答。 :-) - Brad Leach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接