Мне интересно, как динамически изменить стиль кнопки. Я ожидаю, что когда я нажму первую кнопку, стиль должен измениться на «ClickedButton», но для второй должен быть «DefaultButton», соответственно, при нажатии второй кнопки. Эти стили определены в файлеstyles.xaml. Я пытаюсь что-то вроде этого:
Вид:
<ContentView.Resources>
<styleConverter:StyleConverter x:Key = "StyleConverter"
DefaultStyle = "{StaticResource DefaultButton}"
ClickedStyle = "{StaticResource ClickedButton}"/>
</ContentView.Resources>
<Grid RowDefinitions = "19, 2, 42">
<Label Grid.Row = "0" Text = "Alarm state" Margin = "2, 0, 0, 0"/>
<BoxView Grid.Row = "1" HeightRequest = "4" WidthRequest = "0"/>
<Border
WidthRequest = "180"
Grid.Row = "2" Style = "{StaticResource DefaultBorder}">
<Grid
ColumnDefinitions = "58, 58, 58"
x:DataType = "viewModel:OverviewListVM"
>
<Border Style = "{StaticResource LeftRoundedBorder}" >
<Button Padding = "0" Text = "All" HeightRequest = "38"
Style = "{Binding IsButtonAllClicked, Converter = {StaticResource StyleConverter}}"
Command = "{Binding ButtonAllClickedCommand}">
</Button>
</Border>
<Border Style = "{StaticResource RightRoundedBorder}" Grid.Column = "2" >
<Button ImageSource = "warning.png" VerticalOptions = "Center" HorizontalOptions = "Center"
Style = "{Binding IsButtonWarnClicked, Converter = {StaticResource StyleConverter}}"
Command = "{Binding ButtonWarnClickedCommand}"
>
</Button>
</Border>
</Grid>
</Border>
</Grid>
Конвертер:
public class StyleConverter : IValueConverter
{
public Style? DefaultStyle { get; set; }
public Style? ClickedStyle { get; set; }
public object? Convert(object? value, Type? targetType, object? parameter, CultureInfo? culture)
{
return (bool)value! ? ClickedStyle : DefaultStyle;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Модель просмотра:
[ObservableProperty]
private bool isButtonWarnClicked = false;
[ObservableProperty]
private bool isButtonAllClicked = true;
[RelayCommand]
private void ButtonAllClicked()
{
ResetButtons();
IsButtonAllClicked = true;
}
[RelayCommand]
private void ButtonWarnClicked()
{
ResetButtons();
IsButtonWarnClicked = true;
}
private void ResetButtons()
{
IsButtonAllClicked = false;
IsButtonWarnClicked = false;
}
Установлен только стиль для первой кнопки (IsButtonAllClicked = true), когда я нажимаю кнопку предупреждения, срабатывает команда реле, но стиль не меняется. Как динамически изменить стиль с помощью шаблона MVVM?
Edit1: (другой подход согласно @Jessie Zhang -MSFT, изменен только вид)
<Grid RowDefinitions = "19, 2, 42">
<Label Grid.Row = "0" Text = "Alarm state" Style = "{StaticResource TextBlue1}" Margin = "2, 0, 0, 0"/>
<BoxView Grid.Row = "1" HeightRequest = "4" WidthRequest = "0"/>
<Border
WidthRequest = "180"
Grid.Row = "2" Style = "{StaticResource DefaultBorder}">
<Grid
ColumnDefinitions = "58, 58, 58"
x:DataType = "viewModel:OverviewListVM"
>
<Border Style = "{StaticResource LeftRoundedBorder}" >
<Button Text = "All" HeightRequest = "38" Padding = "0" Command = "{Binding ButtonAllClickedCommand}">
<Button.Style>
<Style TargetType = "Button">
<Style.Triggers>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonAllClicked}" Value = "True">
<Setter Property = "Style" Value = "{StaticResource ClickedButton}"/>
</DataTrigger>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonAllClicked}" Value = "False">
<Setter Property = "Style" Value = "{StaticResource DefaultButton}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Border>
<Border Style = "{StaticResource RightRoundedBorder}" Grid.Column = "2" >
<Button ImageSource = "warning.png" Command = "{Binding ButtonWarnClickedCommand}" >
<Button.Style>
<Style TargetType = "Button">
<Style.Triggers>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonWarnClicked}" Value = "True">
<Setter Property = "Style" Value = "{StaticResource ClickedButton}"/>
</DataTrigger>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonWarnClicked}" Value = "False">
<Setter Property = "Style" Value = "{StaticResource DefaultButton}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Border>
</Grid>
</Border>
</Grid>
Но по-прежнему ничего не происходит.
Edit2: (другой подход, изменен Button.Style на Button.Triggers)
новый вид
<Grid RowDefinitions = "19, 2, 42">
<Label Grid.Row = "0" Text = "Alarm state" Style = "{StaticResource TextBlue1}" Margin = "2, 0, 0, 0"/>
<BoxView Grid.Row = "1" HeightRequest = "4" WidthRequest = "0"/>
<Border
WidthRequest = "180"
Grid.Row = "2" Style = "{StaticResource DefaultBorder}">
<Grid
ColumnDefinitions = "58, 58, 58"
x:DataType = "viewModel:OverviewListVM"
>
<Border Style = "{StaticResource LeftRoundedBorder}" >
<Button Text = "All" HeightRequest = "38" Padding = "0" Command = "{Binding ButtonAllClickedCommand}">
<Button.Triggers>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonAllClicked}" Value = "True">
<Setter Property = "Style" Value = "{DynamicResource ClickedButton}"/>
</DataTrigger>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonAllClicked}" Value = "False">
<Setter Property = "Style" Value = "{DynamicResource DefaultButton}"/>
</DataTrigger>
</Button.Triggers>
</Button>
</Border>
<Border Style = "{StaticResource RightRoundedBorder}" Grid.Column = "2" >
<Button ImageSource = "warning.png" Command = "{Binding ButtonWarnClickedCommand}">
<Button.Triggers>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonWarnClicked}" Value = "True">
<Setter Property = "Style" Value = "{DynamicResource ClickedButton}"/>
</DataTrigger>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonWarnClicked}" Value = "False">
<Setter Property = "Style" Value = "{DynamicResource DefaultButton}"/>
</DataTrigger>
</Button.Triggers>
</Button>
</Border>
</Grid>
</Border>
</Grid>
По-прежнему ничего не происходит.
Я добавляю Edit1 в сообщение, но при нажатии по-прежнему ничего не происходит.





Моя ошибка заключалась в следующем: public partial class ViewModel : ObservableObject, INotifyPropertyChanged.
ViewModel расширяет ObservableObject и INotifyPropertyChanged,
когда я удаляю INotifyPropertyChanged, пользовательский интерфейс обновляется. Итак, это работает для меня:
<Button ImageSource = "warning.png" Command = "{Binding ButtonWarnClickedCommand}">
<Button.Triggers>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonWarnClicked}" Value = "True">
<Setter Property = "Style" Value = "{StaticResource ClickedButton}"/>
</DataTrigger>
<DataTrigger TargetType = "Button" Binding = "{Binding IsButtonWarnClicked}" Value = "False">
<Setter Property = "Background" Value = "Yellow"/>
</DataTrigger>
</Button.Triggers>
</Button>
Для достижения этой цели вы можете использовать Триггеры.