How do I bind the visibility of a button to a bool value in my ViewModel?
<Button Height="50" Width="50" Style="{StaticResource MyButtonStyle}"
Command="{Binding SmallDisp}" CommandParameter="{Binding}" Cursor="Hand"
Visibility="{Binding Path=AdvancedFormat}" />
This question is related to
c#
wpf
xaml
data-binding
Since Windows 10 15063 upwards
Since Windows 10 build 15063, there is a new feature called "Implicit Visibility conversion" that binds Visibility to bool value natively - There is no need anymore to use a converter.
My code (which supposes that MVVM is used, and Template 10 as well):
<!-- 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(); }
}
This can be achieved in a very simple way 1. Write this in the view.
<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>
The following is the Boolean property which holds the true/ false value. The following is the code snippet. In my example this property is in UserNote class.
public bool _isHide = false;
public bool IsHide
{
get { return _isHide; }
set
{
_isHide = value;
OnPropertyChanged("IsHide");
}
}
This is the way the IsHide property gets the value.
userNote.IsHide = userNote.IsNoteDeleted;
There's a third way that doesn't require a converter or a change to your view model: use a style:
<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>
I tend to prefer this technique because I use it in a lot of cases where what I'm binding to is not boolean - e.g. displaying an element only if its DataContext
is not null, or implementing multi-state displays where different layouts appear based on the setting of an enum in the view model.
In View:
<Button
Height="50" Width="50"
Style="{StaticResource MyButtonStyle}"
Command="{Binding SmallDisp}" CommandParameter="{Binding}"
Cursor="Hand" Visibility="{Binding Path=AdvancedFormat}"/>
In view Model:
public _advancedFormat = Visibility.visible (whatever you start with)
public Visibility AdvancedFormat
{
get{return _advancedFormat;}
set{
_advancedFormat = value;
//raise property changed here
}
You will need to have a property changed event
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChanged.Raise(this, e);
}
protected void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
This is how they use Model-view-viewmodel
But since you want it binded to a boolean, You will need some converter. Another way is to set a boolean outside and when that button is clicked then set the property_advancedFormat to your desired visibility.
Generally there are two ways to do it, a converter class or a property in the Viewmodel that essentially converts the value for you.
I tend to use the property approach if it is a one off conversion. If you want to reuse it, use the converter. Below, find an example of the converter:
<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
A ViewModel property method would just check the boolean property value, and return a visibility based on that. Be sure to implement INotifyPropertyChanged and call it on both the Boolean and Visibility properties to updated properly.
2 way conversion in c# from boolean to visibility
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;
}
}
}
Source: Stackoverflow.com