简单的 WPF 单选按钮绑定? [英] Simple WPF RadioButton Binding?

查看:21
本文介绍了简单的 WPF 单选按钮绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将一组 3 个单选按钮绑定到值 1、2 或 3 的 int 类型属性的最简单方法是什么?

What is the simplest way to bind a group of 3 radiobuttons to a property of type int for values 1, 2, or 3?

推荐答案

实际上,使用这样的转换器会破坏双向绑定,而且正如我上面所说,您也不能将其与枚举一起使用.更好的方法是对 ListBox 使用简单的样式,如下所示:

Actually, using the converter like that breaks two-way binding, plus as I said above, you can't use that with enumerations either. The better way to do this is with a simple style against a ListBox, like this:

注意:与 DrWPF.com 在他们的示例中所说的相反,不要将 ContentPresenter 放在 RadioButton 内,否则如果您添加带有内容的项目(例如按钮或其他内容),您将无法设置焦点或与之交互.这项技术解决了这个问题.此外,您需要处理文本的灰色化以及删除标签上的边距,否则将无法正确呈现.这种风格也适合你.

Note: Contrary to what DrWPF.com stated in their example, do not put the ContentPresenter inside the RadioButton or else if you add an item with content such as a button or something else, you will not be able to set focus or interact with it. This technique solves that. Also, you need to handle the graying of the text as well as removing of margins on labels or else it will not render correctly. This style handles both for you as well.

<Style x:Key="RadioButtonListItem" TargetType="{x:Type ListBoxItem}" >

    <Setter Property="Template">
        <Setter.Value>

            <ControlTemplate TargetType="ListBoxItem">

                <DockPanel LastChildFill="True" Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Center" >

                    <RadioButton IsChecked="{TemplateBinding IsSelected}" Focusable="False" IsHitTestVisible="False" VerticalAlignment="Center" Margin="0,0,4,0" />

                    <ContentPresenter
                        Content             = "{TemplateBinding ContentControl.Content}"
                        ContentTemplate     = "{TemplateBinding ContentControl.ContentTemplate}"
                        ContentStringFormat = "{TemplateBinding ContentControl.ContentStringFormat}"
                        HorizontalAlignment = "{TemplateBinding Control.HorizontalContentAlignment}"
                        VerticalAlignment   = "{TemplateBinding Control.VerticalContentAlignment}"
                        SnapsToDevicePixels = "{TemplateBinding UIElement.SnapsToDevicePixels}" />

                </DockPanel>

            </ControlTemplate>

        </Setter.Value>

    </Setter>

</Style>

<Style x:Key="RadioButtonList" TargetType="ListBox">

    <Style.Resources>
        <Style TargetType="Label">
            <Setter Property="Padding" Value="0" />
        </Style>
    </Style.Resources>

    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="Background"      Value="Transparent" />

    <Setter Property="ItemContainerStyle" Value="{StaticResource RadioButtonListItem}" />

    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBox}">
                <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="TextBlock.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
        </Trigger>
    </Style.Triggers>

</Style>

<Style x:Key="HorizontalRadioButtonList" BasedOn="{StaticResource RadioButtonList}" TargetType="ListBox">
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel Background="Transparent" Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
</Style>

您现在具有单选按钮的外观和感觉,但是您可以进行双向绑定,并且可以使用枚举.方法如下...

You now have the look and feel of radio buttons, but you can do two-way binding, and you can use an enumeration. Here's how...

<ListBox Style="{StaticResource RadioButtonList}"
    SelectedValue="{Binding SomeVal}"
    SelectedValuePath="Tag">

    <ListBoxItem Tag="{x:Static l:MyEnum.SomeOption}"     >Some option</ListBoxItem>
    <ListBoxItem Tag="{x:Static l:MyEnum.SomeOtherOption}">Some other option</ListBoxItem>
    <ListBoxItem Tag="{x:Static l:MyEnum.YetAnother}"     >Yet another option</ListBoxItem>

</ListBox>

此外,由于我们明确分离了跟踪 ListBoxItem 的样式,而不是将其放入内联,再次如其他示例所示,您现在可以从中创建新样式,以基于每个项目自定义内容,例如作为间距.(如果您只是尝试以 ListBoxItem 为目标,因为键控样式会覆盖通用控件目标,这将不起作用.)

Also, since we explicitly separated out the style that tragets the ListBoxItem rather than putting it inline, again as the other examples have shown, you can now create a new style off of it to customize things on a per-item basis such as spacing. (This will not work if you simply try to target ListBoxItem as the keyed style overrides generic control targets.)

这是一个在每个项目的上方和下方放置 6 边距的示例.(请注意,由于上述原因,您必须如何通过 ItemContainerStyle 属性显式应用样式,而不是简单地将 ListBoxItem 定位到 ListBox 的资源部分.)

Here's an example of putting a margin of 6 above and below each item. (Note how you have to explicitly apply the style via the ItemContainerStyle property and not simply targeting ListBoxItem in the ListBox's resource section for the reason stated above.)

<Window.Resources>
    <Style x:Key="SpacedRadioButtonListItem" TargetType="ListBoxItem" BasedOn="{StaticResource RadioButtonListItem}">
        <Setter Property="Margin" Value="0,6" />
    </Style>
</Window.Resources>

<ListBox Style="{StaticResource RadioButtonList}"
    ItemContainerStyle="{StaticResource SpacedRadioButtonListItem}"
    SelectedValue="{Binding SomeVal}"
    SelectedValuePath="Tag">

    <ListBoxItem Tag="{x:Static l:MyEnum.SomeOption}"     >Some option</ListBoxItem>
    <ListBoxItem Tag="{x:Static l:MyEnum.SomeOtherOption}">Some other option</ListBoxItem>
    <ListBoxItem Tag="{x:Static l:MyEnum.YetAnother}"     >Ter another option</ListBoxItem>

</ListBox>

这篇关于简单的 WPF 单选按钮绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆