WPF隐藏和显示按钮取决于datacontext的值

时间:2020-02-24 21:58:57

标签: c# wpf xaml mvvm

我有2个这样的按钮:

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

我在DataContext中有一个名为IsButton1Visible的布尔变量,如果IsButton1Visible == true,则希望button1可见,如果IsButton1Visible == true,则button2被折叠,如果IsButton1Visible == false,则button2可见。是否可以不使用样式或代码隐藏来完成此操作? XAML答案主要是我想要的。

2 个答案:

答案 0 :(得分:3)

您为什么不想使用样式?到目前为止,这是最简单的方法。

没有样式的一种实现方法是通过布尔到可见性转换器,例如:

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来更改可见性,或者更好的是为整个控件建立模板。转换器是必须在视图和视图模型层之间转换数据时使用的转换器,数据触发器是仅在单向时使用的触发器。

答案 1 :(得分:1)

有一个内置的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>
相关问题