【问题标题】:C# WPF uncheck checkboxesC# WPF 取消选中复选框
【发布时间】:2014-10-31 19:06:00
【问题描述】:

我使用 MS Visual 2013 Express、C# 和 WPF。

在我的程序中有六个复选框,当其中一个被选中时,其他五个应该被取消选中。

我用谷歌搜索了过去两个小时,但作为 C# 初学者找不到解决方案。在java中,我只会写checkbox1.setSelected(false);

我在 C# 代码中添加了一个 clickevent,一个选中和未选中的事件。我在 .xaml 中添加了 CheckedUnchecked,但我不知道如何让它工作。

希望你能帮助我:)

=========================

我的解决方案:

感谢您的帮助。我用你建议的“IsChecked”尝试了一些随机的东西,并且幸运地让它工作。

.Xaml 看起来像:

            <CheckBox x:Name="CheckBox1" ... Checked="CheckBox1_Checked"  />
            <CheckBox x:Name="CheckBox2" ... Checked="CheckBox2_Checked"  />
            <CheckBox x:Name="CheckBox3" ... Checked="CheckBox3_Checked"  />
            <CheckBox x:Name="CheckBox4" ... Checked="CheckBox4_Checked"  />
            <CheckBox x:Name="CheckBox5" ... Checked="CheckBox5_Checked"  />
            <CheckBox x:Name="CheckBox6" ... Checked="CheckBox6_Checked"  />

CheckBox1 的 C# 代码:

    private void CheckBox1_Checked(object sender, RoutedEventArgs e)
    {
        CheckBox1.IsChecked = true;
        CheckBox2.IsChecked = false;
        CheckBox3.IsChecked = false;
        CheckBox4.IsChecked = false;
        CheckBox5.IsChecked = false;
        CheckBox6.IsChecked = false;
    }

例如对于 CheckBox2:

    private void CheckBox2_Checked(object sender, RoutedEventArgs e)
    {
        CheckBox2.IsChecked = true;
        CheckBox1.IsChecked = false;
        CheckBox3.IsChecked = false;
        CheckBox4.IsChecked = false;
        CheckBox5.IsChecked = false;
        CheckBox6.IsChecked = false;
    }

所以说到底,这是一件很容易的事。

【问题讨论】:

  • 对我来说听起来像是RadioButton。为什么不使用它呢?你可以免费获得这种行为!
  • @StefanS:为了澄清,这是只有 一些 选项相互排斥的场景之一吗?如果它们是 all 互斥的,那么一定要使用 RadioButton,正如 BradleyDotNET 建议的那样。但如果只有某些是互斥的,那么 Blam 的建议可能就是你所需要的。
  • CheckBox2.IsChecked = false;看起来很像我的回答。您确实知道要检查答案。

标签: c# wpf


【解决方案1】:
checkbox1.IsChecked = false;

ToggleButton.IsChecked Property

我正在阅读它作为取消选中其他 5 个的特殊功能。
如果您只想一次检查一个,那么 RadioButton 会这样做。
默认情况下,您不能取消选中 RadioButton。
这将允许所有 6 个未选中。

我认为绑定更好,并实现 INotifyPropertyChanged

private Bool cbSecial = false;
private Bool cb1 = false;
private Bool cb2 = false;
public Bool CbSpecial 
{
   get { return cbSecial; }
   set 
   {
      if (value == cbSecial) return;
      cbSecial = value;
      if (cbSpecial) 
      {
          Cb1 = false;
          Cb2 = false;
          ... 
      }
      NotifyPropertyChanged("CbSpecial");
   }
}
public Bool Cb1 
{
   get { return cb1; }
   set 
   {
      if (value == cb1) return;
      cb1 = value;
      NotifyPropertyChanged("Cb1 ");
   }
}

【讨论】:

  • 这里受伤的部分是您必须对所有其他复选框执行此操作。要获得“RadioButton”行为,您可以使用与stackoverflow.com/questions/397556/… 相同的绑定过程,这样会好很多。
  • @BradleyDotNET 是的,我对我编写的解决方案感到奇怪和肮脏,但我想不出在 XAML 之外更简单的方法。也许我会用 DataTriggers 添加一些东西?
  • @furkle 你不需要数据触发器;只需将它们全部绑定到相同的值并使用ValueEqualsConverter 非常适合单选按钮,为CheckBox 这样做会以相同的方式工作。
  • @BradleyDotNET 不,如果您按措辞接受问题,那就再好不过了。 “当其中一个被选中时,其他五个应该被取消选中。”不是当任何或一个 - 当一个。如果有的话,那么我不可能检查其他 5 个。
  • @Blam 是的,但是你怎么知道之前检查过的是哪一个?
【解决方案2】:

BradleyDotNET 是正确的 - 让组中的任何给定 CheckBox 取消选中其余的 CheckBox 本质上是 RadioButton 的功能,您最终不需要做任何事情来实现这种行为。

但是,如果您真的想改用 CheckBoxes,您可以实现的一种方法是在您已绑定 TwoWay 的 ViewModel 中的属性中保留对每个 CheckBox IsChecked 值的引用,并保留一个内部 IEnumerable你的六个值,像这样:

private bool? checkBox1IsChecked = false;
public bool? CheckBox1IsChecked 
{ 
    get { return checkBox1IsChecked;
    set
    {
        UncheckAllCheckBoxes();
        checkBox1IsChecked = true;
    }
}
public bool? CheckBox2IsChecked { get; set; }
...

// include 1 through 6 here
private List<bool?> yourCheckStates = new List<bool> { checkBox1IsChecked, ... };

每当其中一个的状态发生变化时,您都可以使用这样的东西:

private void UncheckAllCheckBoxes()
{
    foreach (bool? cbIsChecked in yourCheckStates)
    {
        cb.IsChecked = false;
    }
}

然后将刚刚更改的值设置为true。每次选中一个复选框时,其他五个将始终未选中。

编辑:如果我误读了这一点,正如 Blam 所建议的那样,并且您的意思是 特别是一个 CheckBox 取消选中所有其他复选框,那么只需在属性中包含对 UncheckAllCheckBoxes() 的调用该特定 CheckBox 的 IsChecked 值,并添加一行以在所有其他设置器中将该特殊 CheckBox 的 IsChecked 设置为 false。

【讨论】:

  • 我不是这样读的。我不是在读一个/任何一个。 “其他 5 个应该取消选中”
  • @Blam 我添加了一个部分来说明这种可能性
【解决方案3】:

您可以采取以下两种方式之一:

  1. RadioButtons 在一个群里
  2. Selector 带有自定义的ItemTemplate

单选按钮:

<RadioButton GroupName="MyGrouping" Content="Option 1" IsChecked="True"/>
<RadioButton GroupName="MyGrouping" Content="Option 2" />
<RadioButton GroupName="MyGrouping" Content="Option 3" />

选择器:

<ListBox ItemsSource="{Binding Path=MyOptions}">
  <ListBox.ItemTemplate>
    <DataTemplate>
        <RadioButton Content="{Binding}"
            IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" />
    </DataTemplate>
  </Listbox.ItemTemplate>
</ListBox>

注意:我选择了ListBox 作为示例,但您可以选择从Selector 派生的任何内容。

【讨论】:

  • 你能解释一下你的绑定在那里做什么吗?我觉得我错过了一步。
  • @furkle:具体是哪个绑定?
  • 啊,我现在明白了 - RadioButton 正在查询其中包含的 ListBoxItem。我花了一秒钟把头绕过去。感谢您的检查。
【解决方案4】:
 {
    if (CheckBox1.Checked)
    {Label1.Text = "Checked Apple"; }
    if (CheckBox1.Checked == false)
    {
        Label1.Text = "Unchecked Apple";
    }

}
protected void CheckBox2_CheckedChanged(object sender, EventArgs e)
{
    if (CheckBox2.Checked)
    { Label1.Text = "Checked Banana"; }
    if (CheckBox2.Checked == false)
    {
        Label1.Text = "Unchecked Banana";
    }
}

【讨论】:

    【解决方案5】:

    您可能会发现这很有用。我有一个“日志记录级别”wpf 菜单,我希望一次只激活 1 个选项(即在选择时取消选中所有其他菜单项)。 我的诀窍是在 xaml 中使用 FindName() 方法和“标记”选项(为一个好的 for 循环生成名称)。这样我就避免了一堆“=false”行,并且每个表单项只有一个共享函数调用。

    <MenuItem Header="Logging">
      <!-- let's use the cool TAG propery to store the debugLevel code. We don't use it, but the idea is cool -->
      <MenuItem Tag="0" Name="mnuLogging0" Header="None" IsCheckable="True" Checked="mnuLogging_Checked"  />
      <MenuItem Tag="1" Name="mnuLogging1" Header="Normal" IsCheckable="True" Checked="mnuLogging_Checked"  />
      <MenuItem Tag="2" Name="mnuLogging2" Header="Debug Level 1" IsCheckable="True" Checked="mnuLogging_Checked"  />
      <MenuItem Tag="3" Name="mnuLogging3" Header="Debug Level 2" IsCheckable="True" Checked="mnuLogging_Checked"   />
    </MenuItem>
    

    取消选中其他选项的功能以及保存设置的奖励代码是:

    private void mnuLogging_Checked(object sender, RoutedEventArgs e) {
      int LogLevel = Convert.ToInt32( ((MenuItem)sender).Tag.ToString());
      Properties.Settings.Default["LogLevel"] = LogLevel.ToString();
      Properties.Settings.Default.Save();
      // Uncheck everybody but me (as determine by "Tag")
      for (int i=0; i < 4; i++) {
        MenuItem item = Main.FindName("mnuLogging"+i) as MenuItem;
        if (i != LogLevel) item.IsChecked = false;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-21
      • 1970-01-01
      • 1970-01-01
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多