【问题标题】:WPF radio button with Image带有图像的 WPF 单选按钮
【发布时间】:2016-01-28 11:57:24
【问题描述】:

我必须创建类似于图片的东西。如果单击其中一个按钮,则其他按钮应变暗。非常感谢!

这就是我需要的

【问题讨论】:

    标签: c# wpf xaml wpf-controls


    【解决方案1】:

    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>
    

    里面的图片可以通过修改Template来创建

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

    默认模板可以在here找到


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

    <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>
    

    【讨论】:

    • 非常感谢。这是完美的解决方案!
    【解决方案2】:

    一段时间后,我找到了另一种方法。可以将ListBox 与自定义ItemTemplate 一起使用,而不是自定义RadioButton

    单个项目的视图模型

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

    列表框标记

    <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。它会自动工作。在我看来,更改当前代码的收入很小,但无论如何感谢您从不同角度看待问题的可能性。
    猜你喜欢
    • 2011-02-11
    • 1970-01-01
    • 2011-04-24
    • 2015-03-15
    • 1970-01-01
    • 2012-06-10
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多