将 Button 的可见性绑定到 ViewModel 中的 bool 值

如何将按钮的可见性绑定到 ViewModel 中的 bool 值?

<Button Height="50" Width="50" Style="{StaticResource MyButtonStyle}"
Command="{Binding SmallDisp}" CommandParameter="{Binding}" Cursor="Hand"
Visibility="{Binding Path=AdvancedFormat}" />
179686 次浏览

假设 AdvancedFormatbool,则需要声明并使用 BooleanToVisibilityConverter:

<!-- In your resources section of the XAML -->
<BooleanToVisibilityConverter x:Key="BoolToVis" />


<!-- In your Button declaration -->
<Button
Height="50" Width="50"
Style="{StaticResource MyButtonStyle}"
Command="{Binding SmallDisp}" CommandParameter="{Binding}"
Cursor="Hand" Visibility="{Binding Path=AdvancedFormat, Converter={StaticResource BoolToVis}}"/>

注意添加的 Converter={StaticResource BoolToVis}

在使用 MVVM 时,这是一种非常常见的模式。理论上你可以自己在 ViewModel 属性上进行转换(也就是说只要把属性本身设置成类型为 Visibility) ,但我不想这么做,因为现在你的关注点分离被 搞乱了。一个项目的可见性应该真正取决于视图。

通常有两种方法可以做到这一点,转换器类或 Viewmodel 中的一个属性实际上可以为您转换值。

如果是一次性转换,我倾向于使用属性方法。如果要重用它,请使用转换器。下面,找到一个转换器的例子:

<ValueConversion(GetType(Boolean), GetType(Visibility))> _
Public Class BoolToVisibilityConverter
Implements IValueConverter


Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert


If value IsNot Nothing Then
If value = True Then
Return Visibility.Visible
Else
Return Visibility.Collapsed
End If
Else
Return Visibility.Collapsed
End If
End Function


Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
Throw New NotImplementedException
End Function
End Class

ViewModel 属性方法只需检查布尔属性值,并根据该值返回可见性。一定要实现 INotifyPropertyChanged,并在 Boolean 和 Visiability 属性上调用它以正确更新。

第三种方法不需要转换器或者视图模型的更改: 使用样式:

<Style TargetType="Button">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>

我倾向于更喜欢这种技术,因为我在很多情况下使用它,我绑定到的是 没有布尔值-例如,显示一个元素只有当它的 DataContext不是空,或实现多状态显示,不同的布局出现在视图模型中的枚举设置的基础上。

视角:

<Button
Height="50" Width="50"
Style="{StaticResource MyButtonStyle}"
Command="{Binding SmallDisp}" CommandParameter="{Binding}"
Cursor="Hand" Visibility="{Binding Path=AdvancedFormat}"/>

视图模型:

public _advancedFormat = Visibility.visible (whatever you start with)


public Visibility AdvancedFormat
{
get{return _advancedFormat;}
set{
_advancedFormat = value;
//raise property changed here
}

您将需要有一个属性更改事件

 protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChanged.Raise(this, e);
}


protected void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}

这就是他们使用模型-视图-视图模型的方式

但是,由于您希望它绑定到一个布尔值,因此需要一些转换器。 另一种方法是在外部设置一个布尔值,当单击该按钮时,将 property _ AdvancedFormat 设置为所需的可见性。

C # 中从布尔型到可见性的2路转换

using System;
using System.Windows;
using System.Windows.Data;


namespace FaceTheWall.converters
{
class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Boolean && (bool)value)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}


public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Visibility && (Visibility)value == Visibility.Visible)
{
return true;
}
return false;
}
}
}

这可以通过一个非常简单的方法来实现 1. 把这个写在视图中。

<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="30">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsHide}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>

  1. 下面是保存 true/false 值的 Boolean 属性。下面是代码段。在我的示例中,此属性位于 UserNote 类中。

    public bool _isHide = false;
    
    
    public bool IsHide
    {
    
    
    get { return _isHide; }
    
    
    set
    {
    _isHide = value;
    OnPropertyChanged("IsHide");
    }
    }
    
  2. This is the way the IsHide property gets the value.

    userNote.IsHide = userNote.IsNoteDeleted;
    

从 Windows 1015063开始

自 Windows 10 build 15063以来,出现了一个名为“隐式可见性转换”的新特性,它将可见性与布尔值绑定在一起——不再需要使用转换器。

(见 https://social.technet.microsoft.com/wiki/contents/articles/34846.uwp-compiled-binding-windows-10-anniversary-update.aspx#Implicit_Visibility_conversion)。

我的代码(假设使用了 MVVM,也使用了模板10) :

<!-- In XAML -->
<StackPanel x:Name="Msg_StackPanel" Visibility="{x:Bind ViewModel.ShowInlineHelp}" Orientation="Horizontal" Margin="0,24,0,0">
<TextBlock Text="Frosty the snowman was a jolly happy soul" Margin="0,0,8,0"/>
<SymbolIcon Symbol="OutlineStar "/>
<TextBlock Text="With a corncob pipe and a button nose" Margin="8,0,0,0"/>
</StackPanel>


<!-- in companion View-Model -->
public bool ShowInlineHelp // using T10 SettingsService
{
get { return (_settings.ShowInlineHelp); }
set { _settings.ShowInlineHelp = !value; base.RaisePropertyChanged(); }
}