Поиск списка отмеченных пунктов в списке списков - PullRequest
0 голосов
/ 17 декабря 2018

Допустим, у меня есть приложение для анкетирования, которое состоит из ItemsControl со списком элементов управления, каждый из которых состоит из Label и ListBox.Элементы в каждом ListBox - это флажки или радиокнопки или что-то в этом роде.

Мой вопрос: Когда флажок установлен, как я могу выяснить, к какому Вопросу применяется флажок?Должен ли я поместить ссылку на вопрос в свойстве Tag?Если да, то как мне это сделать?

Код привязки тега ниже не работает.Связывается с ListBoxItem.Как связать его с элементом ItemsControl?

MainWindow.xaml:

<Window x:Class="ListWithinListTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800">
  <Window.Resources>
    <ResourceDictionary>
      <Style x:Key="ConditionCheckBoxListStyle" TargetType="{x:Type ListBox}">
        <Setter Property="SelectionMode" Value="Multiple" />
        <Setter Property="ItemContainerStyle">
          <Setter.Value>
            <Style TargetType="{x:Type ListBoxItem}" >
              <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
              <Setter Property="Template">
                <Setter.Value>
                  <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <CheckBox IsChecked="{Binding IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"
                              Click="CheckBoxClicked"
                              Tag="{Binding RelativeSource={RelativeSource TemplatedParent}}"
                              >
                      <ContentPresenter></ContentPresenter>
                    </CheckBox>
                  </ControlTemplate>
                </Setter.Value>
              </Setter>
            </Style>
          </Setter.Value>
        </Setter>
      </Style>
    </ResourceDictionary>
  </Window.Resources>

  <Grid>
    <ItemsControl Name="QuizControl" ItemsSource="{Binding QuizQuestions}" ScrollViewer.CanContentScroll="False">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <StackPanel Margin="10 0 10 10" VerticalAlignment="Top">
            <Label Content="{Binding Text}" />
            <ListBox ItemsSource="{Binding Options}"
                     DisplayMemberPath="Text"
                     Tag="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}}"
                     Style="{StaticResource ConditionCheckBoxListStyle}"
                     />
          </StackPanel>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>
  </Grid>
</Window>

MainWindow.xaml.cs:

using System.Windows;
using System.Windows.Controls;

namespace ListWithinListTest
{
    public class Option
    {
        public string Text { get; set; }
        public bool IsSelected { get; set; } = false;
    }

    public class Question
    {
        public string Text { get; set; }
        public Option[] Options { get; set; }
    }

    public class ViewModel
    {
        public Question[] QuizQuestions { get; set; }

        public ViewModel()
        {
            QuizQuestions = new Question[] {
                new Question { Text = "How are you?", Options = new Option[] { new Option { Text = "Good" }, new Option { Text = "Fine" } } },
                new Question { Text = "How's your dog?", Options = new Option[] { new Option { Text = "Sleepy" }, new Option { Text = "Hungry" } } },
            };
        }
    }

    public partial class MainWindow : Window
    {
        private ViewModel viewModel;

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = viewModel = new ViewModel();
        }

        private void CheckBoxClicked(object sender, RoutedEventArgs e)
        {
            Question question = viewModel.QuizQuestions[???];
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Хорошо, я связывался с окном Live Visual Tree, пока, в процессе исключения, я не понял, что ListBox - это то, с чем будет связан Вопрос.Теперь я знаю, что это большой дух, но вот где я с этим.Затем я использовал RelativeSource AncestorType, чтобы найти его, и свойство DataSource, чтобы получить вопрос:

MainWindow.xaml:

                <CheckBox IsChecked="{Binding IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"
                          Click="CheckBoxClicked"
                          Tag="{Binding RelativeSource={RelativeSource AncestorType=ListBox}}"
                          >

MainWindow.xaml.cs:

    private void CheckBoxClicked(object sender, RoutedEventArgs e)
    {
        CheckBox checkBox = (CheckBox)sender;
        ListBox listBox = (ListBox)checkBox.Tag;
        Question question = (Question)listBox.DataContext;
        Debug.WriteLine(question.Text);
    }
0 голосов
/ 17 декабря 2018

Вы связали QuizQuestions с QuizControl, вы можете получить его обратно из свойства ItemsSource.

var  questions = (Question[]) QuizControl.ItemsSource;

РЕДАКТИРОВАТЬ

Похоже, вы получили ответсебя, просто еще один способ, который я хотел бы предложить для вашего исходного вопроса:

Создайте еще одно свойство для вашего класса Option

public class Option
{
    public string Text { get; set; }
    public bool IsSelected { get; set; } = false;
    public int Index{ get; set; }
}

И затем добавьте индекс для каждого из ваших вариантов вопроса.

QuizQuestions = new Question[] {
            new Question { Text = "How are you?", Options = new Option[] { new Option { Text = "Good", Index = 0 }, new Option { Text = "Fine", Index = 0 } } },
            new Question { Text = "How's your dog?", Options = new Option[] { new Option { Text = "Sleepy", Index = 1 }, new Option { Text = "Hungry", Index = 1 } } },
};

В вашем событии CheckBox вы можете получить Индекс опций

private void CheckBoxClicked(object sender, RoutedEventArgs e)
{
    var s = (CheckBox)sender;
    var op = (Option)s.Tag;
    Question question = viewModel.QuizQuestions[op.Index];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...