如何在WPF中更改DynamicResource

3

我有一个包含以下XAML代码的用户控件:

<StackPanel>
    <Label HorizontalContentAlignment="Center">
        <Rectangle Name="iconContainer" Height="120" Width="120" Fill="#FF045189">
            <Rectangle.OpacityMask>
                <VisualBrush Visual="{DynamicResource appbar_disconnect}"/>
            </Rectangle.OpacityMask>
        </Rectangle>
    </Label>
    <TextBlock Name="tBlockPortStatus" Foreground="#FF7C7676" FontWeight="Bold" FontSize="15" Margin="3" TextAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap">PORT STATUS (Testing wrapping text abilities for this control)</TextBlock>
</StackPanel>

我需要使用代码后台或MVVM来更改图标(名为appbar_disconnect),并使用另一个DynamicResource(例如appbar_connect)。 我该如何实现这个目标? 谢谢。


根据什么来更改图标? - SamTh3D3v
基于某些事件触发。但我的问题是如何在运行时更改此DynamicResource以使用其他图标。此UserControl将使用图标和状态消息向用户显示应用程序状态。 - Dariel Nunez
1个回答

2
你的情况看起来最好使用 触发器(Trigger) 而不是 动态资源(DynamicResource) 来处理,但如果你坚持使用 动态资源(DynamicResource),那么你需要在 App.xaml 文件中将状态的图标/图片定义为资源:
 <Application.Resources>
    <Image Source="Icons/disconnect.png" x:Key="AppbarDisconnect"/>
    <Image Source="Icons/connect.png" x:Key="AppbarConnect"/>
    <Image Source="Icons/undefined.png" x:Key="AppbarStatus"/>
</Application.Resources>

假设您的看起来像这样:

<StackPanel>
    <Label HorizontalContentAlignment="Center">
        <Rectangle Name="IconContainer" Height="120" Width="120" Fill="#FF045189">
            <Rectangle.OpacityMask>
                <VisualBrush Visual="{DynamicResource AppbarStatus}"/>
            </Rectangle.OpacityMask>
        </Rectangle>
    </Label>
    <TextBlock Name="TBlockPortStatus" Foreground="#FF7C7676" FontWeight="Bold" FontSize="15" Margin="3" TextAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap">PORT STATUS (Testing wrapping text abilities for this control)</TextBlock>
</StackPanel>

你可以像这样在特定事件(来自代码后台或视图模型)上更新AppbarStatus资源:
Application.Current.Resources["AppbarStatus"] = Application.Current.Resources["AppbarDisconnect"];

更新

如果您想使用DataTrigger,只需在您的用户控件中添加一个属性来保存连接状态:

private bool _connetionStatus;
    public bool ConnectionStatus
    {
        get { return _connetionStatus; }
        set
        {
            if (value == _connetionStatus) return;
            _connetionStatus = value;
            OnPropertyChanged();
        }
    }

DataTrigger应该是不言自明的:

 <StackPanel>
        <Label HorizontalContentAlignment="Center">
            <Rectangle Name="IconContainer" Height="120" Width="120" Fill="#FF045189">
                <Rectangle.Style>
                    <Style TargetType="Rectangle">
                        <Setter Property="OpacityMask">
                            <Setter.Value>
                                <VisualBrush Visual="{DynamicResource AppbarDisconnect}"/>
                            </Setter.Value>
                        </Setter>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ConnectionStatus}" Value="true">
                                <Setter Property="OpacityMask">
                                    <Setter.Value>
                                        <VisualBrush Visual="{DynamicResource AppbarConnect}"/>
                                    </Setter.Value>
                                </Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Rectangle.Style>

            </Rectangle>
        </Label>
        <TextBlock Name="TBlockPortStatus" Foreground="#FF7C7676" FontWeight="Bold" FontSize="15" Margin="3" TextAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap">PORT STATUS (Testing wrapping text abilities for this control)</TextBlock>
    </StackPanel>

我是WPF的新手,所以我想知道如何在特定问题中使用触发器。 - Dariel Nunez
太棒了!谢谢!但是这段代码会改变所有我的瓷砖的图标,好吧,让我更清楚一些,我正在构建一个应用程序来控制串口并向用户提供实时信息,因此我将同时显示多个UC以显示不同的COMPORT状态。我需要能够根据当前端口状态更改每个UC的图标。 - Dariel Nunez
就像我所说的,对于这种场景,DataTrigger 或简单的 Trigger 看起来更加适合,只需将属性(枚举或布尔值)附加到每个 UC 上,并相应地使用触发器更新 VisualBrush。请查看我的更新答案。 - SamTh3D3v
1
太棒了!按照这个想法,我还可以添加更多的状态(例如:阅读、写入、端口通信错误、打印等等)。谢谢! - Dariel Nunez
.Resources 不仅限于 Application,因此您可以在 YourPage.xaml 中将其设置为 ContentPage.Resources,例如并且使用与此答案(更新之前)几乎相同的代码。 - s3c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接