You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过触发器/行为修改WinUI中Image控件的源?

如何通过触发器/行为修改WinUI中Image控件的源?

你现在遇到的问题我完全理解:在WinUI的DataTemplate里有两个Image控件,想根据Model的Type属性(值为Case1或Case2),把TypeImageUri绑定到对应的Image上,之前用Interactivity的DataTriggerBehavior没成功,而且不想用后台代码实现,对吧?

先给你说下为什么之前的写法不行:你在ChangePropertyAction里用Value="{x:Bind TypeImageUri}"是无效的,因为Value属性不是依赖属性,XAML解析器不会处理这个绑定表达式,只会把它当成普通字符串,所以Image的Source会被设置成字符串"{x:Bind TypeImageUri}",而不是实际的图片Uri。

下面给你几个纯XAML的可行方案,你可以根据自己的习惯选择:

方案1:用Style的DataTrigger(轻量无依赖)

这种方法不需要额外引用Behaviors库,是WinUI原生支持的,逻辑也清晰:

<DataTemplate x:DataType="MyModel">
    <Grid>
        <Image x:Name="Image1" Grid.Row="0" Grid.Column="1" Height="16">
            <Image.Style>
                <Style TargetType="Image">
                    <!-- 默认绑定图片,当Type是Case2时清空 -->
                    <Setter Property="Source" Value="{x:Bind TypeImageUri}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{x:Bind Type}" Value="Case2">
                            <Setter Property="Source" Value="{x:Bind x:Null}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
        <Image x:Name="Image2" Grid.Row="1" Grid.Column="1" Height="16">
            <Image.Style>
                <Style TargetType="Image">
                    <!-- 默认空,当Type是Case2时绑定图片 -->
                    <Setter Property="Source" Value="{x:Bind x:Null}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{x:Bind Type}" Value="Case2">
                            <Setter Property="Source" Value="{x:Bind TypeImageUri}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
    </Grid>
</DataTemplate>

方案2:修复Behaviors的写法(如果你一定要用Behaviors)

如果你坚持要用Microsoft.Xaml.Behaviors.WinUI.Managed的话,可以这样修改,把Source的绑定通过BitmapImage来传递:

<DataTemplate x:DataType="MyModel">
    <Grid>
        <Image x:Name="Image1" Grid.Row="0" Grid.Column="1" Height="16" Source="{x:Bind x:Null}" />
        <Image x:Name="Image2" Grid.Row="1" Grid.Column="1" Height="16" Source="{x:Bind x:Null}" />

        <interactivity:Interaction.Behaviors>
            <!-- Case1时给Image1设置图片 -->
            <interactivity:DataTriggerBehavior Binding="{x:Bind Type}" ComparisonCondition="Equal" Value="Case1">
                <interactivity:ChangePropertyAction TargetObject="{Binding ElementName=Image1}" PropertyName="Source">
                    <interactivity:ChangePropertyAction.Value>
                        <BitmapImage UriSource="{x:Bind TypeImageUri}" />
                    </interactivity:ChangePropertyAction.Value>
                </interactivity:ChangePropertyAction>
            </interactivity:DataTriggerBehavior>

            <!-- Case2时给Image2设置图片 -->
            <interactivity:DataTriggerBehavior Binding="{x:Bind Type}" ComparisonCondition="Equal" Value="Case2">
                <interactivity:ChangePropertyAction TargetObject="{Binding ElementName=Image2}" PropertyName="Source">
                    <interactivity:ChangePropertyAction.Value>
                        <BitmapImage UriSource="{x:Bind TypeImageUri}" />
                    </interactivity:ChangePropertyAction.Value>
                </interactivity:ChangePropertyAction>
            </interactivity:DataTriggerBehavior>
        </interactivity:Interaction.Behaviors>
    </Grid>
</DataTemplate>

这里通过直接创建BitmapImage并绑定UriSource,就能正确把图片Uri传递给Image的Source属性了。

方案3:用VisualStateManager(WinUI推荐方式)

这是WinUI官方更推荐的状态管理方式,逻辑清晰,扩展性强:

<DataTemplate x:DataType="MyModel">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="TypeStates">
                <VisualState x:Name="Case1State">
                    <VisualState.StateTriggers>
                        <!-- 当Type等于Case1时激活这个状态 -->
                        <StateTrigger IsActive="{x:Bind Type == 'Case1', Mode=OneWay}" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="Image1.Source" Value="{x:Bind TypeImageUri}" />
                        <Setter Target="Image2.Source" Value="{x:Bind x:Null}" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Case2State">
                    <VisualState.StateTriggers>
                        <!-- 当Type等于Case2时激活这个状态 -->
                        <StateTrigger IsActive="{x:Bind Type == 'Case2', Mode=OneWay}" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="Image1.Source" Value="{x:Bind x:Null}" />
                        <Setter Target="Image2.Source" Value="{x:Bind TypeImageUri}" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <Image x:Name="Image1" Grid.Row="0" Grid.Column="1" Height="16" />
        <Image x:Name="Image2" Grid.Row="1" Grid.Column="1" Height="16" />
    </Grid>
</DataTemplate>

这种方式可以很方便地扩展更多状态,比如以后加Case3的话,只需要新增一个VisualState就行。

备注:内容来源于stack exchange,提问作者xerxos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 10:24:34