2

I have a List view which shows the project names and some buttons for each project which do different actions like adding a comment viewing images for that project etc.. Depending on the project some projects will have some of these buttons disabled sometimes. And some buttons will not be visible in some projects. So there are two things I want to achieve using data binding in this code.

  1. Depending on some boolean variables of the ProjectModel, I need to change the visibility of the buttons. I tried this Binding a Button's visibility to a bool value in ViewModel but it doesn't seem to work on uwp.

  2. For some projects I need to show a different colored image when that option is disabled. So I need to change the ImageSource of ImageBrush depending on the boolean variables of the ProjectModel. For that I tried this Change image using trigger WPF MVVM and those style triggers are not working for uwp.

Please let me know how to do these easily in a UWP app. This is my first UWP app and I am new to these concepts.

<ListView x:Name="stepsListView" Margin="10,0,0,0" RequestedTheme="Dark" FontSize="24" Background="{StaticResource procedure_app_white}" Foreground="Black" BorderThickness="1.5" BorderBrush="Transparent" ItemsSource="{Binding projectList}"  HorizontalAlignment="Left">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.ItemContainerStyle>
        <!-- Item -->
        <ListView.ItemTemplate>
            <DataTemplate>
                <Border BorderThickness="0,0,0,1" BorderBrush="#c0c0c0">
                    <Grid Width="auto" HorizontalAlignment="Stretch" DataContextChanged="Grid_DataContextChanged" >
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="50"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="100"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock VerticalAlignment="Center" FontSize="30" Grid.Row="0" Grid.ColumnSpan="7" Text="{Binding projectName}" Foreground="{StaticResource procedure_app_orange_text }" />

                        <Button x:Name="warningButton" Width="40" Height="40" Grid.Column="1"  Grid.Row="1" Tag="{Binding projectId}" Click="warningButtonClick" Foreground="{StaticResource procedure_app_orange_text }">
                            <Button.Background>
                                <ImageBrush ImageSource="Asset/step_ncwr.png">
                                </ImageBrush>
                            </Button.Background>
                        </Button>
                        <Button x:Name="commentButton" Width="40" Height="40" Grid.Column="2"   Grid.Row="1"  Tag="{Binding projectId}" Click="CommentButtonClick" Foreground="{StaticResource procedure_app_orange_text }" IsTapEnabled="True">
                        <Button.Background>
                            <ImageBrush ImageSource="Asset/step_comment.png">
                            </ImageBrush>
                        </Button.Background>
                        </Button>
                        <Button x:Name="imageButton" Width="40" Height="40" Grid.Column="3"  Grid.Row="1"  Tag="{Binding projectId}" Click="ImageButtonClick" Foreground="{StaticResource procedure_app_orange_text }">
                            <Button.Background>
                                <ImageBrush ImageSource="Asset/step_image.png">
                                </ImageBrush>
                            </Button.Background>
                        </Button>
                    </Grid>
                </Border>
            </DataTemplate>
        </ListView.ItemTemplate>

Community
  • 1
  • 1
Madhu
  • 1,209
  • 2
  • 22
  • 28
  • Are all of the disabled images the same image? – DotNetRussell Jul 14 '16 at 12:31
  • @AnthonyRussell For e.g In project 1 the comment button will be disabled. So I need to show another icon for the comments button which shows as it is disabled in gray color. In the project 2 the image button will be disabled. In the project 3 I need to hide the comment button. etc.. I want to do two actions. Hide some buttons and Change the image of some buttons. These will vary on the project. For each button there will be two images the orange color image and the gray color image. – Madhu Jul 14 '16 at 12:47
  • You shouldn't have to create a gray color. Just by disabling the button it should gray scale your image – DotNetRussell Jul 14 '16 at 12:48
  • @AnthonyRussell when I set IsEnabled="False" to a button above, it goes invisible completely. But when I click on a row the row get highlighted and then I see a square border for that button. – Madhu Jul 14 '16 at 12:52
  • and this is why you don't ask 2 questions in one :) now you have two answers each answering one question – AlexDrenea Jul 14 '16 at 13:01

3 Answers3

5

The Visibility property is not of type bool so that's why you cannot bind it to the Boolean property in your ViewModel directly.

You need to do so though a converter. As the name sais, a Converter is a class that helps you convert from one type to another in for Bindings to work. In your case, you need to convert a boolean value of true to a Visibility value of Visible.

There is a built-in converter in UWP but I will show you how to create one since you will probably need to write other converters in the future:

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;

namespace YourNamespace
{
    public class BooleanToVisibilityConverter : IValueConverter
    {
        public Visibility OnTrue { get; set; }
        public Visibility OnFalse { get; set; }

        public BooleanToVisibilityConverter()
        {
            OnFalse = Visibility.Collapsed;
            OnTrue = Visibility.Visible;
        }

        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var v = (bool)value;

            return v ? OnTrue : OnFalse;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            if (value is Visibility == false)
                return DependencyProperty.UnsetValue;

            if ((Visibility)value == OnTrue)
                return true;
            else
                return false;
        }
    }
}

The converter allows you to convert Boolean values to Visibility values and by default will convert True to Visibility.Visible and False to Visibility.Collapsed, but it is configurable as you'll see below.

Next you need to declare your converter in your XAML. In the Page or UserControl you need to perform this steps:

  1. Declare the converter Namespace (use the same namespace you used when creating the converter class

    xmlns:converters="using:YourNamespace"
  2. Instantiate the converter in your Page / UserControl Resources

    <Page.Resources> <converters:BooleanToVisibilityConverter x:Key="bool2vis"/> <converters:BooleanToVisibilityConverter x:Key="bool2visInverse" OnTrue=Collapsed, OnFalse=Visible/> </Page.Resources>

  3. Use your converter in your binding:

    <Button x:Name="warningButton" Width="40" Height="40" Grid.Column="1" Grid.Row="1" Tag="{Binding projectId}" Click="warningButtonClick" Foreground="{StaticResource procedure_app_orange_text }" Visibility="{Binding IsVisible, Converter={StaticResource bool2vis}}">

AlexDrenea
  • 7,981
  • 1
  • 32
  • 49
  • Thanks Alex got that to working. I tried this earlier also but I was missing the xmlns:converters="using:YourNamespace" part. That's why it didn't work. It works great now. :-) I'll mark this as the answer. – Madhu Jul 14 '16 at 13:12
1

So I think what you're going to want to do is modify the button's template.

If you look at the MSDN article on Button Styles and Tempaltes you will see the default Button Style.

Inside this default style you'll see this

  <VisualState x:Name="Disabled">
     <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
                                       Storyboard.TargetProperty="Background">
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                  <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                   Storyboard.TargetProperty="BorderBrush">
                  <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}" />
        </ObjectAnimationUsingKeyFrames>
     </Storyboard>
  </VisualState>

See where it say's Disabled? Everything inside of here defines how the button looks when it is disabled. I would research how to retemplate a button and then mess around with this style.

Start here Xaml Custom Styles in UWP

DotNetRussell
  • 9,716
  • 10
  • 56
  • 111
0

To hide a ui element just do this:

this.MyComponent.Visibility = Visibility.Collapsed;

And to make it visible do this:

this.MyComponent.Visibility = Visibility.Visible;

This is almost identical to passing a true, false, and what is most people who read this title will actually be looking for.

Tyler S. Loeper
  • 816
  • 11
  • 22