XAML 动态资源未更新.NET MAUI中的ImageButton样式

hzbexzde  于 2022-12-07  发布在  .NET
关注(0)|答案(2)|浏览(205)

我定义了两个ContentPage级别的样式来动态绑定到ImageButton。当ImageButton单击事件被调用时,它应该切换ImageButton样式,但这并没有发生。
下面是具有样式和ImageButton定义的ContentPage内容:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SampleMobile.SamplePage"
             Title="">

    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="defaultStyle" TargetType="ImageButton">
                <Setter Property="BorderColor" Value="Grey"/>
                <Setter Property="BorderWidth" Value="2" />
            </Style>
            <Style x:Key="selectedStyle" TargetType="ImageButton">
                <Setter Property="BorderColor" Value="Blue"/>
                <Setter Property="BorderWidth" Value="5" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <Grid RowDefinitions="50, 100, 5, 100, 5, 50, 100, 100, 100" ColumnDefinitions="*, *, *, *"
          Padding="25, 35, 25, 35" ColumnSpacing="5" RadioButtonGroup.GroupName="mobileNetworks">

        <Label Grid.Row="0" Grid.ColumnSpan="4"
            Text="Select Network"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
        <ImageButton Source="first.png" Grid.Row="1" Grid.Column="0" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{DynamicResource imageButtonStyle}"/>
        <ImageButton Source="second.png" Grid.Row="1" Grid.Column="1" BorderWidth="2" HeightRequest="50" WidthRequest="50" BorderColor="Grey" CornerRadius="10"/>
        <ImageButton Source="third.png" Grid.Row="1" Grid.Column="2" BorderWidth="2" HeightRequest="50" WidthRequest="50" BorderColor="Grey" CornerRadius="10"/>
        <ImageButton Source="fourth.png" Grid.Row="1" Grid.Column="3" BorderWidth="2" HeightRequest="50" WidthRequest="50" BorderColor="Grey" CornerRadius="10"/>

    </Grid>

</ContentPage>

下面是代码隐藏文件,其中设置了第一个样式,并在click事件处理程序中设置了第二个样式:

public partial class SamplePage : ContentPage
{
    public SamplePage()
    {
        InitializeComponent();
        Resources["imageButtonStyle"] = Resources["defaultStyle"];
    }

    private void SelectImage(object sender, EventArgs e)
    {
        Resources["imageButtonStyle"] = Resources["selectedStyle"];
    
    }
}

我仍在努力找出问题所在,以及为什么它没有按预期工作。

cs7cruho

cs7cruho1#

你可以用这个。
首先为ImageButton指定一个类似x:Name="Image1"的名称
我添加了2个按钮来更改它并返回。

<ContentPage.Resources>
    <ResourceDictionary>
        <Style x:Key="defaultStyle" TargetType="ImageButton">
            <Setter Property="BorderColor" Value="Gray"/>
            <Setter Property="BorderWidth" Value="2" />
        </Style>
        <Style x:Key="selectedStyle" TargetType="ImageButton">
            <Setter Property="BorderColor" Value="Blue"/>
            <Setter Property="BorderWidth" Value="5" />
        </Style>
    </ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
    <Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
        <Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
    </Frame>
    <ImageButton x:Name="Image1"  Source="balzwart.png" Style="{DynamicResource defaultStyle}" />

    <Button Text="Change" Clicked="Button_Clicked" />
    <Button Text="Back" Clicked="Button_Clicked_1" />
</StackLayout>

对于按钮单击

private void Button_Clicked(object sender, EventArgs e)
    {
        Image1.Style = (Style)Resources["selectedStyle"];
    }

    private void Button_Clicked_1(object sender, EventArgs e)
    {
        Image1.Style = (Style)Resources["defaultStyle"];
    }

在此查找https://github.com/borisoprit/DynamicSO

n7taea2i

n7taea2i2#

不要在运行时操作样式,* 这只是一个半好的主意,无论如何都应该以不同的方式操作 *,我建议您做如下所示的事情,而不是使用可视状态和ImageButton的唯一样式:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SelectedImageSample.MainPage">

  <ContentPage.Resources>
    <ResourceDictionary>
      <Style x:Key="ImageButtonStyle" TargetType="ImageButton">
        <Setter Property="VisualStateManager.VisualStateGroups">
          <VisualStateGroupList>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Selected">
                <VisualState.Setters>
                  <Setter Property="BorderColor" Value="Blue" />
                </VisualState.Setters>
              </VisualState>
            </VisualStateGroup>
          </VisualStateGroupList>
        </Setter>
      </Style>
    </ResourceDictionary>
  </ContentPage.Resources>

  <Grid RowDefinitions="50, 100, 5, 100, 5, 50, 100, 100, 100" ColumnDefinitions="*, *, *, *"
        Padding="25, 35, 25, 35" ColumnSpacing="5" RadioButtonGroup.GroupName="mobileNetworks">

    <Label Grid.Row="0" Grid.ColumnSpan="4"
           Text="Select Network"
           VerticalOptions="Center" 
           HorizontalOptions="Center" />
    <ImageButton Source="first.png" Grid.Row="1" Grid.Column="0" BorderWidth="2"  HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{StaticResource ImageButtonStyle}"/>
    <ImageButton Source="second.png" Grid.Row="1" Grid.Column="1" BorderWidth="2" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{StaticResource ImageButtonStyle}"/>
    <ImageButton Source="third.png" Grid.Row="1" Grid.Column="2" BorderWidth="2" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{StaticResource ImageButtonStyle}"/>
    <ImageButton Source="fourth.png" Grid.Row="1" Grid.Column="3" BorderWidth="2" HeightRequest="50" WidthRequest="50" CornerRadius="10" Clicked="SelectImage" Style="{StaticResource ImageButtonStyle}"/>

  </Grid>

</ContentPage>

然后,在程式码后置中,您可以使用事件行程常式来设定[视觉化状态],如下所示:

private void SelectImage(object sender, EventArgs e)
{
    if (sender is ImageButton imageButton)
    {
        VisualStateManager.GoToState(imageButton, "Selected");
    }
}

这只是一个最简单的演示,演示了如何在不操作资源中的样式的情况下完成此操作。如果您想再次取消选择ImageButton,您需要实现一些逻辑和一个UnselectedVisual State。

更新1

通过添加IsSelected属性(例如通过继承)在按钮上存储某种状态可能会很有用。然后可以相应地更新可视状态。

更新2

如果不想扩展ImageButton,也可以使用Attached Property来存储按钮的状态。

相关问题