WPF Tips: Uncheckable radio buttons

来源:互联网 发布:pantheon linux 编辑:程序博客网 时间:2024/05/21 17:01

Radio button 通常的行为是:某一组 Radio button 只能有一个被选中( Checked ),当一个被选中是其余的 Radio button 自动 Uncheck。

但是,有没有什么办法让这一组 Radio button 在被点击之后,再回复到任何一个 Radio button 都没有被选中的状态呢?比如说,两个 Radio button:Radio 1 和 Radio 2,初始状态下任何一个 radio button 都没有被选中,现在我们点击 Radio 1,则 Radio 1 被选中;再次点击 Radio 1,则 Radio 1 回复到没有被选中的状态,Radio 2 的状态也不受影响。能否实现这样的功能呢?网上搜不到现成的答案,但实际上是可以实现的。

实现的关键是利用 RadioButton 的 PreviewMouseLeftButtonDown 事件,该事件能够获得 RadioButton 被点击时,它之前的状态。有了这个状态我们就可以判断出这个 RadioButton 应该从未选中的状态置为选中的状态,还是从被选中的状态置为未选中的状态。


我写了个小例子,可从此处下载源代码和编译好之后的可执行文件(基于.Net 3.5)

http://download.csdn.net/detail/xinyaping/4513569


源代码如下:


MainWindow.xaml

<Window x:Class="RadioButttonUnCheckDemo.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Width="300" Height="95" WindowStyle="ToolWindow"         Title="Demo: Uncheckable radio buttons">        <Grid Height="24" Margin="0,0,0,0">        <Grid.ColumnDefinitions>            <ColumnDefinition Width="80" />            <ColumnDefinition />            <ColumnDefinition Width="120" />        </Grid.ColumnDefinitions>                <Label Grid.Column="0" VerticalAlignment="Center">Please select: </Label>                <WrapPanel Grid.Column="1">            <RadioButton Name="radio1" Content="1" Margin="5,0,5,0" GroupName="GroupName1"                          PreviewMouseLeftButtonDown="RadioButton_PreviewMouseLeftButtonDown"                          Checked="RadioButton_StateChanged"                          Unchecked="RadioButton_StateChanged" />            <RadioButton Name="radio2" Content="2" Margin="5,0,5,0" GroupName="GroupName1"                          PreviewMouseLeftButtonDown="RadioButton_PreviewMouseLeftButtonDown"                         Checked="RadioButton_StateChanged"                          Unchecked="RadioButton_StateChanged" />        </WrapPanel>        <Label Grid.Column="2" VerticalAlignment="Center" Name="labelResult" />    </Grid> </Window>

MainWindow.xaml.cs

namespace RadioButttonUnCheckDemo{    using System.Windows;    using System.Windows.Controls;    using System.Windows.Input;    /// <summary>    /// Interaction logic for MainWindow.xaml    /// </summary>    public partial class MainWindow : Window    {        /// <summary>        /// Initializes a new instance of the <see cref="MainWindow"/> class.        /// </summary>        public MainWindow()        {            this.InitializeComponent();        }        /// <summary>        /// Gets a value indicating whether RadioButton radio1 is checked.        /// </summary>        /// <value>        ///     <c>true</c> if RadioButton radio1 is radio1 checked; otherwise, <c>false</c>.        /// </value>        private bool IsRadio1Checked        {            get { return this.radio1.IsChecked == null ? false : (bool)this.radio1.IsChecked; }        }        /// <summary>        /// Gets a value indicating whether RadioButton radio2 is checked.        /// </summary>        /// <value>        ///     <c>true</c> if RadioButton radio2 is radio1 checked; otherwise, <c>false</c>.        /// </value>        private bool IsRadio2Checked        {            get { return this.radio2.IsChecked == null ? false : (bool)this.radio2.IsChecked; }        }        /// <summary>        /// Handles the PreviewMouseLeftButtonDown event of the RadioButton control.        /// </summary>        /// <param name="sender">The source of the event.</param>        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>        private void RadioButton_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)        {            if (sender != null && sender is RadioButton)            {                RadioButton radioButton = sender as RadioButton;                bool isChecked =                    radioButton.IsChecked == null ?                    false :                    (bool)radioButton.IsChecked;                if (isChecked)                {                    radioButton.IsChecked = false;                    e.Handled = true;                }            }        }        /// <summary>        /// Handles the StateChanged event of the RadioButton control.        /// </summary>        /// <param name="sender">The source of the event.</param>        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>        private void RadioButton_StateChanged(object sender, RoutedEventArgs e)        {            this.SetResult();        }        /// <summary>        /// Sets the result.        /// </summary>        private void SetResult()        {            if (!this.IsRadio1Checked && !this.IsRadio2Checked)            {                this.labelResult.Content = "Selected: N/A";            }            else if (this.IsRadio1Checked)            {                this.labelResult.Content = "Selected: Radio 1";            }            else if (this.IsRadio2Checked)            {                this.labelResult.Content = "Selected: Radio 2";            }        }    }}

可从此处下载源代码和编译好之后的可执行文件(基于.Net 3.5)

http://download.csdn.net/detail/xinyaping/4513569


原创粉丝点击