WPF按钮图像仅显示在最后一个控件中

WPF按钮图像仅显示在最后一个控件中,wpf,image,xaml,button,Wpf,Image,Xaml,Button,我是WPF的新手,这里可能缺少一些简单的东西。如果我有3个控件,则只有最后一个控件将显示我指定的原始图像 任何帮助都将不胜感激。谢谢 瑞安 主窗口 <Grid> <Grid.RowDefinitions> <RowDefinition Height="200*"/> <RowDefinition Height="60" /> </Grid.RowDefiniti

我是WPF的新手,这里可能缺少一些简单的东西。如果我有3个控件,则只有最后一个控件将显示我指定的原始图像

任何帮助都将不胜感激。谢谢 瑞安

主窗口

<Grid>

        <Grid.RowDefinitions>
            <RowDefinition Height="200*"/>
            <RowDefinition Height="60" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="85" />
            <ColumnDefinition Width="85" />
            <ColumnDefinition Width="85" />
            <ColumnDefinition Width="85" />
            <ColumnDefinition Width="300" />
        </Grid.ColumnDefinitions>

            <Grid Grid.Row="1">
                <but:ListButton OriginalImage="/CustomItemsPanel;component/ListBox/Images/add.png"
                            DisableImage="/CustomItemsPanel;component/ListBox/Images/addunselect.png"

            />
        </Grid  >
        <Grid Grid.Row="1" Grid.Column="1"  >
            <but:ListButton OriginalImage="/CustomItemsPanel;component/ListBox/Images/add.png"
                            DisableImage="/CustomItemsPanel;component/ListBox/Images/addunselect.png"

            />
        </Grid  >
        <Grid Grid.Row="1" Grid.Column="2"  >
            <but:ListButton OriginalImage="/CustomItemsPanel;component/ListBox/Images/add.png"
                            DisableImage="/CustomItemsPanel;component/ListBox/Images/addunselect.png"

            />
        </Grid>
</Grid>

我要回答我自己的问题。Bitbonk很好地解释了我做错了什么以及样式是如何工作的。谢谢

 <Style x:Key="Toggle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid Cursor="Hand">
                    <Border Name="back" Margin="0,1,0,0" Background="{StaticResource ButtonBackground}">
                        <Image Name="imgBut" Source="{Binding Path=(OriginalImage), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ListButton}}}" />
                    </Border>
                    <Border BorderThickness="1" BorderBrush="#FF004F92">
                        <Border BorderThickness="0,0,1,0" BorderBrush="#FF101D29" />
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True" >
                        <Setter TargetName="back" Property="Background" Value="{StaticResource ButtonBackgroundMouseOver}"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False" >
                        <Setter TargetName="imgBut" Property="Source" Value="{Binding Path=(DisableImage), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ListButton}}}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

发生这种情况是因为您对按钮的“切换”样式。您在其中使用的图像仅创建一次(因为样式仅计算一次),并且无法将图像添加到多个按钮(在WPF中,每个视觉对象只能有一个父级)。因此,应用样式的最后一个按钮将赢得并从上一个按钮中窃取图像

如果要在样式中修改VisualTree,则应在ControlTemplate中执行此操作。

在样式中使用x:Shared=“False”

<Style x:Key="Toggle" x:Shared="False" TargetType="{x:Type Button}">
    ......
</Style>

......

它真的总是最后一个有效吗?如果你只有一个,它会工作;如果你有五个,只有第五个?虽然XAML看起来非常简单,但我的第一个调试步骤可能是将XAML简化为更简单的东西,比如只有一个带有三个ListButton的StackPanel。如果有一个,它可以工作,如果有5个,第5个图像将显示。我尝试使用stackpanel,得到了相同的结果:(
 <Style x:Key="Toggle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid Cursor="Hand">
                    <Border Name="back" Margin="0,1,0,0" Background="{StaticResource ButtonBackground}">
                        <Image Name="imgBut" Source="{Binding Path=(OriginalImage), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ListButton}}}" />
                    </Border>
                    <Border BorderThickness="1" BorderBrush="#FF004F92">
                        <Border BorderThickness="0,0,1,0" BorderBrush="#FF101D29" />
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True" >
                        <Setter TargetName="back" Property="Background" Value="{StaticResource ButtonBackgroundMouseOver}"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False" >
                        <Setter TargetName="imgBut" Property="Source" Value="{Binding Path=(DisableImage), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ListButton}}}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="Toggle" x:Shared="False" TargetType="{x:Type Button}">
    ......
</Style>