如何在 XAML 中构建问卷 UserControl,其问题共享相同的答案? [英] How can I build a questionnaire UserControl in XAML whose questions share the same answers?

查看:17
本文介绍了如何在 XAML 中构建问卷 UserControl,其问题共享相同的答案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想构建一个 UserControl 来表示问卷,如下图所示(忽略样式的缺失).

I'd like to build a UserControl to represent a questionnaire, something like that pictured below (ignore the lack of styling).

我希望能够在XAML中指定重要的内容,比如

I want to be able to specify the important content in XAML, such as

<local:QuestionnaireControl>
  <local:QuestionnaireControl.Questions>
    <local:QuestionAndAnswers Number="1" Question="Is this working?" />
    <local:QuestionAndAnswers Number="2" Question="Are these questions sharing answers?" />
  </local:QuestionnaireControl.Questions>
  <local:QuestionnaireControl.Answers>
    <local:Answer Value="0" Text="Yes" />
    <local:Answer Value="1" Text="No" />
    <local:Answer Value="2" Text="Help Me Please" />
  </local:QuestionnaireControl.Answers>
</local:QuestionnaireControl>

所以我有以下 QuestionnaireControl.xaml

<UserControl x:Class="MyProject.QuestionnaireControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             xmlns:local="clr-namespace:MyProject"
             DataContext="{Binding RelativeSource={RelativeSource Self}}"
             d:DataContext="{d:DesignInstance Type=local:QuestionnaireControl, IsDesignTimeCreatable=True}">
    <ItemsControl ItemsSource="{Binding Questions}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Number, StringFormat='{}{0}.'}" Margin="0,0,10,0" />
                    <TextBlock Text="{Binding Question}" Width="220"/>
                    <ItemsControl ItemsSource="{Binding Answers}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal"/>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <RadioButton
                                        Content="{Binding Text}"
                                        IsChecked="{Binding IsSelected}"
                                        GroupName="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=local:QuestionAndAnswers}, Path=Question}"
                                        Margin="0,0,10,0"
                                    />
                                </StackPanel>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</UserControl>

以及下面的QuestionnaireControl.xaml.cs

public partial class QuestionnaireControl : UserControl
{
    public QuestionnaireControl()
    {
        InitializeComponent();

        if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
        {
            Questions = new List<QuestionAndAnswers> {
                new QuestionAndAnswers() { Number=1, Question="Do you like pizza?" },
                new QuestionAndAnswers() { Number=2, Question="Can you surf?" },
                new QuestionAndAnswers() { Number=3, Question="Are you funny?" },
                new QuestionAndAnswers() { Number=4, Question="Is Monday your favorite day of the week?" },
                new QuestionAndAnswers() { Number=5, Question="Have you been to Paris?" },
                new QuestionAndAnswers() { Number=6, Question="When sleeping, do you snore?" },
                new QuestionAndAnswers() { Number=7, Question="Could you be living in a dream?" }
            };
            Answers = new List<Answer> {
                new Answer() { Value=1, Text="Yes", IsSelected=false },
                new Answer() { Value=2, Text="No", IsSelected=false },
                new Answer() { Value=3, Text="Sort Of", IsSelected=false },
            };
        }
        else
        {
            Questions = new List<QuestionAndAnswers>();
            Answers = new List<Answer>();
        }

        // Copy Answers to each QuestionAndAnswers.
        foreach (QuestionAndAnswers qa in Questions)
        {
            qa.Answers = new List<Answer>(Answers);
        }
    }

    public List<QuestionAndAnswers> Questions
    {
        get { return (List<QuestionAndAnswers>)GetValue(QuestionsProperty); }
        set { SetValue(QuestionsProperty, value); }
    }

    public static readonly DependencyProperty QuestionsProperty =
        DependencyProperty.Register("Questions", typeof(List<QuestionAndAnswers>), typeof(QuestionnaireControl), new FrameworkPropertyMetadata(new List<QuestionAndAnswers>()));

    public List<Answer> Answers
    {
        get { return (List<Answer>)GetValue(AnswersProperty); }
        set { SetValue(AnswersProperty, value); }
    }

    public static readonly DependencyProperty AnswersProperty =
        DependencyProperty.Register("Answers", typeof(List<Answer>), typeof(QuestionnaireControl), new FrameworkPropertyMetadata(new List<Answer>()));
}

public class QuestionAndAnswers
{
    public int Number { get; set; }
    public string Question { get; set; }
    public List<Answer> Answers { get; set; }
}

public class Answer
{
    public string Text { get; set; }
    public int Value { get; set; }
    public bool IsSelected { get; set; }
}

使用上面的代码,我可以在 Visual Studio 设计器中生成 QuestionnaireControl 上面的图像.但是,当我实际使用 QuestionnaireControl 时,根据上面的示例,会呈现问题而不是答案.有谁知道我需要调整什么?

With the code above, I'm able to produce the image above of the QuestionnaireControl in the Visual Studio designer. But when I actually use the QuestionnaireControl, per the example above, the questions are rendered but not the answers. Does anyone know what I need to tweak?

推荐答案

如果将控件的 Answers 属性的类型更改为 ObservableCollection 你可以处理它的 CollectionChanged 事件并复制每个问题的答案:

If you change the type of the Answers property of the control to ObservableCollection<Answer> you could handle its CollectionChanged event and copy the answers to each question:

public partial class QuestionnaireControl : UserControl
{
    public QuestionnaireControl()
    {
        InitializeComponent();
        Questions = new List<QuestionAndAnswers>();
        Answers = new ObservableCollection<Answer>();
        Answers.CollectionChanged += Answers_CollectionChanged;
    }

    private void Answers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        foreach (var question in Questions)
        {
            question.Answers = new List<Answer>();
            foreach (var answer in Answers)
            {
                question.Answers.Add(new Answer() { Text = answer.Text, Value = answer.Value, IsSelected = answer.IsSelected });
            }
        }
    }

    public List<QuestionAndAnswers> Questions
    {
        get { return (List<QuestionAndAnswers>)GetValue(QuestionsProperty); }
        set { SetValue(QuestionsProperty, value); }
    }

    public static readonly DependencyProperty QuestionsProperty =
        DependencyProperty.Register("Questions", typeof(List<QuestionAndAnswers>), typeof(QuestionnaireControl));

    public ObservableCollection<Answer> Answers
    {
        get { return (ObservableCollection<Answer>)GetValue(AnswersProperty); }
        set { SetValue(AnswersProperty, value); }
    }

    public static readonly DependencyProperty AnswersProperty =
        DependencyProperty.Register("Answers", typeof(ObservableCollection<Answer>), typeof(QuestionnaireControl), new FrameworkPropertyMetadata(null));

}

这篇关于如何在 XAML 中构建问卷 UserControl,其问题共享相同的答案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆