ListView的DataTemplate中的单选按钮组

3
我有一个问题是关于以下答案的扩展。它指出单选按钮的GroupName具有非常广泛的范围,通常最好让容器自动分配GroupName。

https://dev59.com/0G025IYBdhLWcg3wW0oc#6062697

如果我使用静态的GroupName,那么所有的RadioButton共享一个组。(如链接中所示的答案。)
然而,如果我不使用GroupName,则每个单独的RadioButton被视为自己的组。我只能假设它是使用DataTemplate或CellTemplate作为“父级”,以便自动分配GroupName。
我有一个Question列表在StackPanel中显示。每个Question都显示在一个UserControl中。每个Question包含一个Answers的ListView。每个Answer都有一个布尔属性,表示已选择答案,该属性绑定到DataTemplate内的RadioButton。
我的精简XAML如下:
    <ListView ItemsSource="{Binding AnswerList}" >
      <ListView.View>
        <GridView>
          <!-- Other columns here -->
          <GridViewColumn>
            <GridViewColumn.CellTemplate>
              <DataTemplate>
                <RadioButton IsChecked="{Binding Path=AnswerChecked}" />
              </DataTemplate>
            </GridViewColumn.CellTemplate>
          </GridViewColumn>
        </GridView>
      </ListView.View>
    </ListView>

我认为我没有其他选择,只能使用ListView,因为我需要能够关闭和打开其他列,并且需要显示两个或更多答案。
有没有办法告诉单选按钮它是UserControl的一部分,而不是DataTemplate,以便于GroupName?
我考虑为每个UserControl分配一个GUID,并将RadioButtons的GroupName绑定到GUID的字符串上,但这似乎过度和笨拙。
编辑:为了视觉参考,UI大致如下(我的注释在括号内):
(问题的StackPanel绑定到问题集合)
  1. 问题控制(包含绑定到答案集合的ListView, '|' 分隔列)
    • [ ] | 答案1(未选中的答案对象,文本为“答案1”)
    • [ ] | 答案2
    • [*] | 答案3(已选中的答案对象,文本为“答案3”)
  2. 第16任总统是谁
    • [ ] | 卡尔·马克思
    • [*] | 亚伯拉罕·林肯
    • [ ] | 理查德·尼克松
  3. 一个摩尔氢的重量是多少
    • [ ] | 10克
    • [ ] | 0.1克
    • [ ] | 1克

我曾考虑为每个UserControl分配一个GUID,并将RadioButtons的GroupName绑定到GUID的字符串,但这似乎过于冗长和笨拙。而且它并没有起作用。最终我还是遇到了之前的问题,每个RadioButton都被视为独立的。 - River-Claire Williamson
1
似乎我在这方面走错了路。单选按钮(至少在4.5中)将自动按其容器进行分组。 - River-Claire Williamson
2个回答

3
您应该能够使用类似以下的东西:

你可以像这样摆脱一些问题

 <RadioButton GroupName="{Binding}" IsChecked="{Binding Path=AnswerChecked}" />

这将把它们全部分组在一起。

如果ListView是QuestionControl的一部分,为什么不绑定QuestionText作为问题应该是唯一的。

<RadioButton GroupName="{Binding Path=TheQuestionText}" IsChecked="{Binding Path=AnswerChecked}" />

你可能需要使用FindAncestorDataTemplate中访问你的Questioncontrol

 <RadioButton GroupName="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type QuestionControl}}, Path=QuestionText"}  />

这会导致所有问题控件中的RadioButton被视为一个组。我需要的是将每个问题控件中的RadioButton视为一个组,与其他问题控件中的RadioButton分开处理。 - River-Claire Williamson
啊..我有点难以理解你的布局是如何组合在一起的,你能发一张截图吗? - sa_ddam213
1
你能不能只使用问题文本作为单选按钮组名称,因为问题应该是唯一的? - sa_ddam213
问题文本不一定是唯一的,但它们有独特的ID。将组名绑定到唯一的ID会导致每个单选按钮表现得好像它们在一个1组中。 - River-Claire Williamson

0

这让我度过了瓶颈期,但我不会接受这个解决方案。这个方案远非最佳。

我转而使用 CheckBox,在 VM 中为 Answer 的 PropertyChanged 回调添加了此代码,并向 Answer 对象添加了一个名为“AllowAnswer”的属性。

    void AnswerItemChanged(object sender, PropertyChangedEventArgs e)
    {
    if (e.PropertyName == "AnswerChecked")
    {
        bool hasAnswer = false;
        foreach(Answer answer in Answers)
        {
            if (answer.AnswerChecked == true)
            {
                hasAnswer = true;
                break;
            }
        }

        foreach (Answer answer in Answers)
        {
            substep.PropertyChanged -= AnswerItemChanged;

            if (hasAnswer && !answer.AnswerChecked )
            {
                answer.AllowAnswer = false;
            }
            else 
            {
                answer.AllowAnswer = true;
            }

            substep.PropertyChanged += AnswerItemChanged;
        }
    }
    }

这使得复选框能够模仿单选按钮的互斥功能。然而,在实践中,这更加笨拙,因为用户现在必须取消选择一个答案才能选择另一个答案。


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