问题
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.
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.
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>
回答1:
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:
Declare the converter Namespace (use the same namespace you used when creating the converter class
xmlns:converters="using:YourNamespace"
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>
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}}">
回答2:
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
回答3:
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.
来源:https://stackoverflow.com/questions/38374143/uwp-app-show-hide-button-using-binding