Search code examples
winui-3winui

How can I bind the visibility of a XAML Component to a model property?


I want to bind the visibility of

<TextBlock Text="{x:Bind ViewModel.Time}" />

to a variable.

I tried to bind it to Visibility enum and google the problem. Found no solution for winui 3.


Solution

  • As @Simon Mourier mentioned in a comment, you can just bind to a "Visibility" property in your ViewModel:

    public partial class ViewModel : ObservableObject
    {
        [ObservableProperty]
        private string time = DateTime.Now.ToString("HH:mm:ss");
    
        [ObservableProperty]
        private Visibility timeVisibility = Visibility.Collapsed;
    }
    

    Note:

    I'm using the CommunityToolkit.Mvvm NuGet package to implement the ViewModel.

    <TextBlock
        Text="{x:Bind ViewModel.Time}"
        Visibility="{x:Bind ViewModel.TimeVisibility, Mode=OneWay}" />
    

    Or, if you want to avoid "UI" related code in your ViewModel, you can bind the TextBlock's Visibility to a bool and use a ValueConverter like this:

    public partial class ViewModel : ObservableObject
    {
        [ObservableProperty]
        private string time = DateTime.Now.ToString();
    
        [ObservableProperty]
        private bool isTimeVisible = false;
    }
    
    public class TrueToVisibleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            return value is bool boolValue && boolValue is true
                ? Visibility.Visible
                : Visibility.Collapsed;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
    
    <TextBlock
        Text="{x:Bind ViewModel.Time}"
        Visibility="{x:Bind ViewModel.IsTimeVisible, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}" />