ListView DataTemplate中的单选按钮组

时间:2012-12-26 17:24:51

标签: c# wpf listview mvvm .net-4.0

我的问题是以下答案的扩展。它声明单选按钮的GroupName具有非常宽的范围,并且通常最好让容器自动分配GroupName。

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

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

但是,如果我不使用GroupName,则会将每个单独的RadioButton视为单独存在于组中。我只能假设它使用DataTemplate或CellTemplate作为'父',以便自动分配GroupName。

我在StackPanel中有一个问题列表。每个问题都显示在UserControl中。每个问题都包含一个ListView of Answers。每个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 of Questions绑定到一组问题)

  1. 问题控制(包含绑定到Answers'|'分隔列的集合​​的ListView)
    • [] |答案1(未经检查的答案对象,文字“答案1”)
    • [] |答案2
    • [*] |答案3(已检查的答案对象,文字“答案3”)
  2. 谁是第16任总统
    • [] |卡尔马克思
    • [*] |亚伯拉罕林肯
    • [] |理查德尼克松
  3. 1摩尔氢的重量是多少
    • [] | 10克
    • [] | 0.1克
    • [] | 1克

2 个答案:

答案 0 :(得分:1)

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

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

这应该将它们组合在一起。

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

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

您可能必须使用FindAncestorQuestioncontrol

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

答案 1 :(得分:0)

这使我摆脱了僵局,但我不接受它。这个解决方案远非最优。

我切换到使用CheckBox,在VM中我将此代码添加到了Answer的PropertyChanged回调中,并添加了一个Property&#34; AllowAnswer&#34;到答案对象。

    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的互斥功能。然而,它在实践中更加愚蠢,因为用户现在必须取消选择另一个答案才能选择。