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

时间:2011-08-09 18:15:47

标签: c# wpf xaml data-binding

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

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

7 个答案:

答案 0 :(得分:183)

假设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类型)虽然我不想这样做,因为现在你 搞乱了关注点分离。项目的可见性应该完全取决于视图。

答案 1 :(得分:87)

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

<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不为空时显示元素,或者实现多状态显示,其中根据视图模型中枚举的设置显示不同的布局。

答案 2 :(得分:9)

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;
        }
    }
}

答案 3 :(得分:4)

通常有两种方法可以做到这一点,一个转换器类或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属性方法只检查boolean属性值,并根据该值返回可见性。一定要实现INotifyPropertyChanged并在Boolean和Visibility属性上调用它以正确更新。

答案 4 :(得分:3)

在视图中:

<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)); 
    } 

这是他们使用Model-view-viewmodel

的方式

但是既然你想把它绑定到布尔值,你需要一些转换器。 另一种方法是在外部设置一个布尔值,当单击该按钮时,将property_advancedFormat设置为所需的可见性。

答案 5 :(得分:2)

这可以通过一种非常简单的方式实现 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. 这是 IsHide 属性获取值的方式。

    userNote.IsHide = userNote.IsNoteDeleted;
    

答案 6 :(得分:1)

自Windows 10 15063起,

自Windows 10内部版本15063起,就有一个称为“隐式可见性转换”的新功能,该功能将“可见性”与bool值本身绑定在一起-不再需要使用转换器。

(请参阅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(); }
}