ListView 的 DataTemplate 中的单选按钮组

Posted

技术标签:

【中文标题】ListView 的 DataTemplate 中的单选按钮组【英文标题】:Radio Button Group in a ListView's DataTemplate 【发布时间】:2012-12-12 05:00:10 【问题描述】:

我的问题是以下答案的扩展。它指出单选按钮的 GroupName 范围很广,通常最好让 GroupName 由容器自动分配。

https://***.com/a/6062697/907920

如果我使用静态 GroupName,那么所有 RadioButtons 都会共享该组。 (如链接中的答案所示。)

但是,如果我不使用 GroupName,那么每个单独的 RadioButton 都会被视为单独在一个组中。为了自动分配 GroupName,我只能假设它使用 DataTemplate 或 CellTemplate 作为它的“父级”。

我在 StackPanel 中有一个问题列表。每个问题都显示在 UserControl 中。每个问题都包含一个答案列表视图。每个答案都有一个布尔属性,表明答案已被选中,该属性绑定到 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 的一部分,而不是用于 GroupName 的 DataTemplate?

我考虑为每个 UserControl 分配一个 GUID,并将 RadioButtons 的 GroupName 绑定到 GUID 的字符串,但这似乎过于笨拙。

编辑:为了视觉参考,用户界面大约像这样流动,括号中是我的注释:

(绑定到问题集合的问题堆栈面板)

    问题控制(包含绑定到答案集合的 ListView '|' 分隔列) [ ] |答案 1(带有文本“答案 1”的未选中答案对象) [ ] |答案 2 [*] |答案 3(带有文本“答案 3”的选中答案对象) 第十六任总统是谁 [ ] |卡尔·马克思 [*] |亚伯拉罕·林肯 [ ] |理查德尼克松 一摩尔氢气的重量是多少 [ ] | 10克 [ ] | .1g [ ] | 1克

【问题讨论】:

“我考虑为每个 UserControl 分配一个 GUID 并将 RadioButtons 的 GroupName 绑定到 GUID 的字符串,但这似乎过于笨拙。” ——也没有奏效。我最终遇到了与以前相同的问题。每个 RadioButton 都被视为独立于其他按钮。 似乎我用这个来找错树了。单选按钮(至少在 4.5 中)将自动按其容器分组。 【参考方案1】:

你应该能够摆脱这样的事情

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

【讨论】:

这会导致 Question 控件中的所有 RadioButtons 都被视为一组的一部分。我需要将每个问题控件的 RadioButtons 视为一组,与其他问题控件中的其他 RadioButtons 分开。 啊.. 我无法理解你的布局是如何组合在一起的,你能发个截图吗? 你能不能只使用问题文本作为 RadioButtons 组名称,因为问题应该是唯一的? 问题文本不能保证是唯一的,但它们确实有唯一的 ID。将组名绑定到唯一的 Id 会导致每个单选按钮的行为就像它们在一组 1 中一样。【参考方案2】:

这让我摆脱了困境,但我不会接受。这个解决方案远非最佳。

我切换到使用 CheckBox,并在 VM 中将此代码添加到 Answer 的 PropertyChanged 回调中,并将属性“AllowAnswer”添加到 Answer 对象。

    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;
        
    
    

这允许 CheckBox 模仿 RadioButton 的互斥功能。然而,在实践中它更加笨拙,因为用户现在必须取消选择一个答案才能选择另一个答案。

【讨论】:

以上是关于ListView 的 DataTemplate 中的单选按钮组的主要内容,如果未能解决你的问题,请参考以下文章

wpf ListView DataTemplate方式的鼠标悬停和选中更改背景色

如何使用类似表格的 DataTemplate 在 UWP ListView 中动态缩放列宽

ListView DataTemplate 中的 ColumnDefinition 未扩展到全宽

为什么ListView中的DataTemplate不会自动更新其绑定?

如何在复选框事件上访问嵌套listview datatemplate中的标签名称

DataContext 用于在 DataTemplate 中将 UserControl 与 ViewModel 绑定