【问题标题】:WPF hide and show button depending on datacontext valueWPF 根据数据上下文值隐藏和显示按钮
【发布时间】:2020-02-24 21:58:57
【问题描述】:

我有 2 个这样的按钮:

<Button x:Name="button1" Content="Button 1"/>
<Button x:Name="button2" Content="Button 2"/>

我的 DataContext 中有一个名为 IsButton1Visible 的 bool 变量,如果 IsButton1Visible == true,我希望 button1 可见,button2 折叠,如果 IsButton1Visible == false, button1 折叠,button2 可见。是否可以在不使用样式或代码隐藏的情况下完成此操作? XAML 答案主要是我正在寻找的。​​p>

【问题讨论】:

    标签: c# wpf xaml mvvm


    【解决方案1】:

    为什么不想使用样式?这是迄今为止最简单的方法。

    没有样式的一种方法是通过布尔到可见性转换器,即这样的:

    public class BooleanToVisibilityConverter : IValueConverter
    {
        #region IValueConverter Members
    
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return false;
            var invert = (parameter == null) ? false : Boolean.Parse(parameter.ToString());
            if ((Boolean)value ^ invert)
                return Visibility.Visible;
            else
                return Visibility.Hidden;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    
        #endregion
    }
    

    然后你会像这样使用它:

    <Button x:Name="button1" Content="Button 1" Visibility="{Binding IsButton1Visible, Converter={StaticResource BooleanToVisibilityConverter}}" />
    <Button x:Name="button2" Content="Button 2" Visibility="{Binding IsButton1Visible, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=true}" />
    

    说真的,只需在样式中使用 DataTrigger 即可更改可见性,或者更好的是,模板化整个控件。当数据必须在视图和视图模型层之间转换时,您使用转换器,当它是单向时,您使用数据触发器。

    【讨论】:

    • 触发器是最合适的方法,为这种类型的操作引入转换器总是会导致捷径和坏习惯。
    • @slugster 同意。 OP 专门标记了 MVVM,每当您发现自己必须使用转换器将数据转换为视图可以使用的东西时,通常表明您的视图模型层没有正常工作。
    • 好吧,我会用我猜的风格。我一开始并不想这样做,因为我最终会创建大量相似的样式。
    • @Mr-RandomQC 是的,这对于 WPF 应用程序来说是很正常的,但是您可以通过使用 Style.BasedOn property 继承其他样式的属性来大大减少重复代码的数量。此外,如果您的许多样式中都使用了某些颜色等值,那么您可以将它们声明为资源并使用 StaticResource/DynamicResource 在您的样式中绑定到它们。
    • 我不知道 Style.BasedOn,看起来不错。谢谢@MarkFeldman!
    【解决方案2】:

    有一个内置的BooleanToVisibilityConverter 可用于在boolVisibility 之间进行转换:

    <Button x:Name="button1" Content="Button 1">
        <Button.Visibility>
            <Binding Path="IsButton1Visible">
                <Binding.Converter>
                    <BooleanToVisibilityConverter />
                </Binding.Converter>
            </Binding>
        </Button.Visibility>
    </Button>
    

    您可以定义自己的反转转换器并以相同的方式绑定第二个按钮的Visibility 属性:

    public class BooleanToVisibilityNegationConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
            (bool)value ? Visibility.Collapsed : Visibility.Visible;
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
            ((Visibility)value) == Visibility.Visible ? false : true;
    }
    

    XAML:

    <Button x:Name="button1" Content="Button 1">
        <Button.Visibility>
            <Binding Path="IsButton1Visible">
                <Binding.Converter>
                    <local:BooleanToVisibilityNegationConverter />
                </Binding.Converter>
            </Binding>
        </Button.Visibility>
    </Button>
    

    这不需要定义任何样式或编写任何代码隐藏,但它确实需要您定义上面的转换器类。

    另一个唯一的 XAML 解决方案是为第二个按钮定义一个内联 Style。这需要零代码:

    <Button x:Name="button1" Content="Button 1">
        <Button.Visibility>
            <Binding Path="IsButton1Visible">
                <Binding.Converter>
                    <BooleanToVisibilityConverter />
                </Binding.Converter>
            </Binding>
        </Button.Visibility>
    </Button>
    
    <Button x:Name="button2" Content="Button 2">
        <Button.Style>
            <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsVisible, ElementName=button1}" Value="True">
                        <Setter Property="Visibility" Value="Collapsed" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 2014-05-12
      • 2021-09-02
      • 2018-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多