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

ray*_*0nd 115 c# data-binding wpf xaml

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

<Button Height="50" Width="50" Style="{StaticResource MyButtonStyle}"
    Command="{Binding SmallDisp}" CommandParameter="{Binding}" Cursor="Hand"
    Visibility="{Binding Path=AdvancedFormat}" />
Run Code Online (Sandbox Code Playgroud)

dle*_*lev 193

假设AdvancedFormat是a bool,你需要声明并使用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}}"/>
Run Code Online (Sandbox Code Playgroud)

注意添加Converter={StaticResource BoolToVis}.

在使用MVVM时,这是一种非常常见的模式.从理论上讲,你可以自己在ViewModel属性上进行转换(即只是将属性本身设置为类型Visibility)虽然我宁愿不这样做,因为现在你正在搞乱关注点的分离.项目的可见性应该完全取决于View.

  • 就个人而言,我不介意在我的ViewModels中放置Visibility类型的属性.我知道这是我的异端,但对我来说,这给了View更多的灵活性,而不是更少.如果一个视图不想使用它,它就没有,如果有的话,它可以减少必须使用转换器或样式触发器的痛苦.是的,这会将我的ViewModel与演示技术(例如WPF与ASP.Net MVC)联系起来,但我很少需要将这些技术与重构相结合,如果我*做*不会吓到我的话. (3认同)
  • @ raym0nd当然.ViewModel仅返回一个布尔值,表示条件.如果您的View碰巧将该布尔值解释为是否显示某些内容,那么这取决于View.请注意,另一个View仍然可以不同地解释它. (2认同)
  • 是的,因为这只是一个按摩一个值的助手类.视图模型仍将位于模型和视图之间. (2认同)
  • 另外,请记住MVVM是一种设计模式,因此您必须执行自己的有关其实现的规则.此外,有时候实现某些事情的唯一方法是在View的Model,ViewModel或XAML部分之外.在Codebehind中添加一些东西并不是一种罪过.如果可能的话,将它放在ViewModel中更符合MVVM模式. (2认同)

Rob*_*ney 93

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

<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>
Run Code Online (Sandbox Code Playgroud)

我倾向于喜欢这种技术,因为我在许多情况下使用它,我绑定的不是布尔值 - 例如,只有当它DataContext不为空时才显示元素,或者实现多状态显示,其中不同的布局基于在视图模型中设置枚举.

  • 一般来说,我觉得转换器是黑客,我不喜欢它们.我认为这是我个人品味的问题,而不是从工程角度对利弊的冷静评估,但我避免使用它们. (5认同)

Ber*_*rty 10

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 正如已经提到的,WPF中已经内置了一个.你不需要自己做. (7认同)

Var*_*mus 7

自 Windows 10 15063 起

自 Windows 10 build 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(); }
}
Run Code Online (Sandbox Code Playgroud)

  • 该问题要求 WPF 答案。WPF 目前不支持编译绑定(又名 {x:Bind})。以下是相关问题,其中包含指向用户制作的 x:Bind 实现的链接:[https://github.com/dotnet/wpf/issues/130](https://github.com/dotnet/wpf/issues/ 130) (3认同)