Binding a Button's visibility to a bool value in ViewModel
Assuming AdvancedFormat
is a bool
, you need to declare and use a 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}}"/>
Note the added Converter={StaticResource BoolToVis}
.
This is a very common pattern when working with MVVM. In theory you could do the conversion yourself on the ViewModel property (i.e. just make the property itself of type Visibility
) though I would prefer not to do that, since now you are messing with the separation of concerns. An item's visbility should really be up to the View.
Binding a bool to button visibility
Don't set the local Visibility
property:
<Button Canvas.Left="300" Canvas.Top="235" Click="ShowEquipmentItems" Cursor="Hand">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Content">
<Setter.Value>
<StackPanel>
<Image Source="../Images/Green spot icon.png" Height="35" Width="35" />
</StackPanel>
</Setter.Value>
</Setter>
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ShowButtons}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Local values take precedence over style setters as explained in the docs: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-value-precedence
You should also raise the PropertyChanged
event for the ShowButtons
property in your view model:
public class CabinViewViewModel : BindableBase, ICabinViewViewModel
{
private bool _showButtons;
public bool ShowButtons
{
get { return _showButtons; }
set { SetProperty(ref _showButtons, value); }
}
...
}
Binding xaml property visibility to ViewModel, control with button
ViewModel should implement INotifyPropertyChanged
interface for informing View about changes.
public class ViewModel : INotifyPropertyChanged
{
// Implementing INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName);
}
// In the setter of property raise event to inform view about changes
private Boolean _state = true;
public Boolean State
{
get
{
return _state;
}
set
{
_state = value;
RaisePropertyChanged();
}
}
}
Binding visibility of rectangle control to button's isEnabled property
Create an instance of a BooleanToVisibilityConverter
converter in any resources in scope.
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
Then bind the Visibility
of the rectangle to the IsEnabled
property of your button by referring to it using the element name BtnUC
. By specifying the converter, true
will be converted to Visible
and false
to Collapsed
.
<Rectangle Grid.Column="0" Fill="LightGray" Margin="-4,0,0,0"
Visibility="{Binding IsEnabled, ElementName=BtnUC, Converter={StaticResource BooleanToVisibilityConverter}}"/>
Alternatively, if there is no button name, refer to the parent Button
via RelativeSource
.
<Rectangle Grid.Column="0" Fill="LightGray" Margin="-4,0,0,0"
Visibility="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType={x:Type Button}}, Converter={StaticResource BooleanToVisibilityConverter}}"/>
Returning bool from ViewModel to View binding
You can improve your code in ViewModel
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private bool isconnecting ;
public bool isConnecting
{
get
{
return isconnecting;
}
set
{
if (isconnecting != value)
{
isconnecting = value;
NotifyPropertyChanged();
}
}
}
Bind visibility of text box to view model property in a content template
try to set data source for textbox binding. How do I use WPF bindings with RelativeSource?
smth like this. typeOfAncestor is UserControl or a Window
{Binding FilterRows, Converter={StaticResource BooleanToCollapsedConverter},
RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
Is it a good design to bind to visibility in viewmodel
It is a matter of taste really. I personally prefer the converter approach in most cases. The benefit of defining the view model property as a bool
is that it has no dependency upon any view related type.
This is especially important if you share (or intend to share) your view models between several different types of client applications.
But as far as MVVM is concerned, you don't really break the pattern by adding a Visibility
property to the view model class. Also, this might actually be better than using a converter for performance reasons if you intend to display a lot of view model instances in an ItemsControl
.
Related Topics
Convert a List to a String in C#
Selectsinglenode Returns Null When Tag Contains Xmlnamespace
Resize Image Proportionally with Maxheight and Maxwidth Constraints
Remove Weird Characters ( a with Hat) from SQL Server Varchar Column
Xml Serialization - Hide Null Values
The Type Is Defined in an Assembly That Is Not Referenced, How to Find the Cause
Deserialize Nested, Complex Json Object to Just a String C#
How to Detect Installed Version of Ms-Office
Resolving an Ambiguous Reference
Web App Blocked While Processing Another Web App on Sharing Same Session
Find an Item in a List by Linq
Generics Open and Closed Constructed Types
C# Equivalent of SQL Server Datatypes
Start a .Net Process as a Different User
Create Instance of Generic Type Whose Constructor Requires a Parameter