WPF带有图像的单选按钮

12

我需要创建类似图片的东西。如果其中一个按钮被点击,其他按钮应该变暗。非常感谢!

这就是我需要的

输入图像描述

2个回答

32

通过样式触发器,当RadioButton未被选中时,您可以更改Opacity

<RadioButton.Style>                    
    <Style TargetType="RadioButton">                        
        <Style.Triggers>
            <Trigger Property="IsChecked" Value="False">
                <Setter Property="Opacity" Value="0.5"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</RadioButton.Style>

修改 模板 可以创建内部的图片。

<RadioButton.Template>
    <ControlTemplate TargetType="RadioButton">
        <!-- new template -->
    </ControlTemplate>
</RadioButton.Template>

默认模板可以在这里找到。


我的原始模板看起来像这样(我已经在ItemsControl中添加了3个单选按钮,第2个被选中)

输入图像说明

<StackPanel Grid.Row="0" Grid.Column="1">
    <StackPanel.Resources>
        <Style x:Key="Flag" TargetType="RadioButton">
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="False">
                    <Setter Property="Opacity" Value="0.5"/>
                </Trigger>
            </Style.Triggers>

            <Setter Property="BorderThickness" Value="2"/>

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="RadioButton">
                        <Border BorderThickness="{TemplateBinding BorderThickness}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                Background="Transparent"
                                CornerRadius="20">                                    
                            <Image Source="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </StackPanel.Resources>

    <ItemsControl>
        <RadioButton Content="../Resources/radio.png" Style="{StaticResource Flag}" BorderBrush="Red" Width="40" Height="40"/>
        <RadioButton Content="../Resources/radio.png" Style="{StaticResource Flag}" BorderBrush="Orange" Width="40" Height="40"/>
        <RadioButton Content="../Resources/radio.png" Style="{StaticResource Flag}" BorderBrush="Green" Width="40" Height="40"/>
    </ItemsControl>
</StackPanel>

非常感谢。这是完美的解决方案! - Dmitrii Polianskii

3

经过一段时间的探索,我找到了另一种方法。不必使用自定义 RadioButton,可以使用带有自定义 ItemTemplate 的 ListBox。

单个项目的 ViewModel

public class CountryVm
{
    public CountryVm()
    {
        ImageUri = new Uri("Resources/rgb.png", UriKind.Relative);            
    }

    public string Name { get; set; }

    public Uri ImageUri { get; set; }
}
    ListBox标记
<ListBox Name="Countries" ItemsSource="{Binding}" SelectionMode="Single"
            HorizontalAlignment="Center" VerticalAlignment="Top" 
            BorderThickness="0">

    <!--changing default ListBoxItem to hide selection highlight-->
    <ListBox.Resources>
        <Style TargetType="ListBoxItem">                    
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Background="Transparent" SnapsToDevicePixels="true">
                            <ContentPresenter />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>

    <!--changing default orientation-->
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type wpf2:CountryVm}">
            <!--circle image border-->
            <Border Name="Border"
                    BorderThickness="1" BorderBrush="Black" Background="{x:Null}"
                    Width="48" Height="48" CornerRadius="24" Margin="4"
                    ToolTip="{Binding Name}">

                <Image Source="{Binding Path=ImageUri}" Stretch="None"/>

                <!--changing selected item opacity via trigger-->
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Opacity" Value="0.5"/>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=IsSelected, 
                                                           RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                                         Value="True">
                                <Setter Property="Opacity" Value="1"/>                                        
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

测试DataContext

DataContext = new List<CountryVm>
{
    new CountryVm {Name = "123"},
    new CountryVm {Name = "Abc"},
    new CountryVm {Name = "Xyz"},
};

结果

在此输入图片描述


这是一个有趣的想法。现在我正在运行时加载可用语言,然后创建单选按钮并将它们添加为子元素。使用这种方法,我只需将对象数组应用于ListBox即可自动工作。在我看来,当前代码的变化很小,但无论如何感谢提供从不同角度看问题的机会。 - Dmitrii Polianskii

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