В WPF, Как добавить переключатель, флажок, comboBox в зависимости от типа, который настроен в базе данных? - PullRequest
0 голосов
/ 06 января 2019

Абсолютно я новичок в WPF, мне нужно решить проблему. Кто-нибудь может дать мне пример кода XAML без использования кода позади. На основе questType (Check, radio, combo) Необходимо создать элемент управления на основе ObserverableCollection.

public class Order
{
  public int OrderCode {get;set;}
  public string Description {get;set;}
  public ObserverableCollection<question> Questions{get;set;}
}
public class question
{
   public string questType {get;set;}
   public string Question {get;set;}
   public ObserverableCollection<Answer> Answers {get;set;}
}
public class Answer
{
    public string Ans{get; set;}
}

Основано на типе квеста (чек, радио, комбо) Элемент управления должен быть создан на основе ObserverableCollection. пример: 1001 Карандаш Пол? oMale oFemale другой [] Флажок1 [] Флажок2 1002 пера поста? Да Да

1 Ответ

0 голосов
/ 06 января 2019

Вот как бы я это сделал:

Код:

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;

namespace Ans
{

    public class Order
    {
        public int OrderCode { get; set; }
        public string Description { get; set; }
        public ObservableCollection<Question> Questions { get; set; }
    }
    public class Question
    {
        public string questType { get; set; }
        public string Label { get; set; }
        public ObservableCollection<Answer> Answers { get; set; }
    }
    public class Answer
    {
        public string Ans { get; set; }
        public bool IsSelected { get; set; }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        #region Order

        /// <summary>
        /// Order Dependency Property
        /// </summary>
        public static readonly DependencyProperty OrderProperty =
            DependencyProperty.Register("Order", typeof(Order), typeof(MainWindow),
                new FrameworkPropertyMetadata((Order)null));

        /// <summary>
        /// Gets or sets the Order property. This dependency property 
        /// indicates ....
        /// </summary>
        public Order Order
        {
            get { return (Order)GetValue(OrderProperty); }
            set { SetValue(OrderProperty, value); }
        }

        #endregion



        public MainWindow()
        {
            InitializeComponent();

            Order = new Order()
            {
                Questions = new ObservableCollection<Question>()
                {
                    new Question()
                    {
                        questType = "Combo",
                        Label = "Combo",
                        Answers = new ObservableCollection<Answer>()
                        {
                            new Answer(){Ans = "Female"},
                            new Answer(){Ans = "Male"}
                        }
                    },
                    new Question()
                    {
                        questType = "Check",
                        Label = "Multi",
                        Answers = new ObservableCollection<Answer>()
                        {
                            new Answer(){Ans = "Female"},
                            new Answer(){Ans = "Male"}
                        }
                    },
                    new Question()
                    {
                        questType = "Radio",
                        Label = "Radio",
                        Answers = new ObservableCollection<Answer>()
                        {
                            new Answer(){Ans = "Female"},
                            new Answer(){Ans = "Male"}
                        }
                    }



                }
            };

            DataContext = this;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            foreach(Question q in Order.Questions)
            {
                Console.WriteLine( q.Label + " : " + string.Join(", " , q.Answers.Where(a=>a.IsSelected).Select(a=>a.Ans)) );
            }
        }
    }
}

XAML:

<Window x:Class="Ans.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Ans"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        <DataTemplate x:Key="ComboQuestion">
            <ComboBox ItemsSource="{Binding Answers}">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Ans}"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
                <ComboBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ComboBoxItem}">
                        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
                    </Style>
                </ComboBox.ItemContainerStyle>
            </ComboBox>
        </DataTemplate>
        <DataTemplate x:Key="CheckQuestion">
            <ItemsControl ItemsSource="{Binding Answers}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <CheckBox Content="{Binding Ans}" IsChecked="{Binding IsSelected, Mode=TwoWay}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
        <DataTemplate x:Key="RadioQuestion">
            <ItemsControl ItemsSource="{Binding Answers}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <RadioButton Content="{Binding Ans}" IsChecked="{Binding IsSelected, Mode=TwoWay}" GroupName="{Binding DataContext.Label, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </Window.Resources>
    <Grid>

        <ItemsControl ItemsSource="{Binding Order.Questions}" Grid.IsSharedSizeScope="True">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" SharedSizeGroup="Label"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>

                        <TextBlock Text="{Binding Label}"/>

                        <ContentControl x:Name="ccQuestion" Grid.Column="1" Content="{Binding}" Margin="10"/>
                    </Grid>
                    <DataTemplate.Triggers>
                        <DataTrigger Binding="{Binding questType}" Value="Combo">
                            <Setter TargetName="ccQuestion" Property="ContentTemplate" Value="{StaticResource ComboQuestion}"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding questType}" Value="Check">
                            <Setter TargetName="ccQuestion" Property="ContentTemplate" Value="{StaticResource CheckQuestion}"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding questType}" Value="Radio">
                            <Setter TargetName="ccQuestion" Property="ContentTemplate" Value="{StaticResource RadioQuestion}"/>
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>


        <Button Content="Order" Click="Button_Click" VerticalAlignment="Bottom"/>
    </Grid>
</Window>

Единственное, что я добавил в вашу модель - это свойство IsSelected, которое позволяет узнать, был ли выбран этот ответ.

Другая важная вещь - радио. Их свойство GroupName определяет область действия. Таким образом, если имя группы не установлено, то при нажатии на радио в одном вопросе он отменяет выбор радио в другом вопросе. В своем решении я использовал вопросительный ярлык, однако он работает только в том случае, если ярлыки уникальны.

Другой момент заключается в том, что триггеры данных в порядке, если у вас есть 3-5 типов вопросов и если они основаны только на типе вопроса. Однако для более сложных сценариев вы можете искать ItemTemplateSelector. Он позволяет писать код C #, который будет выбирать шаблон на основе каждого элемента в ItemsControl.

...