WPF - комбинированный список флажков - привязка выбрана? - PullRequest
1 голос
/ 12 ноября 2010

Я реализовал ComboBox из CheckBox, который выглядит довольно хорошо в графическом интерфейсе, но у меня возникают проблемы с его функциональным использованием.

Основная проблема, с которой я сталкиваюсь - это выяснить, какие блокина самом деле проверены.Во время выполнения ComboBox.SelectedItem работает правильно, но если я перебираю все элементы, они всегда возвращают IsSelected == false.

Есть идеи?

Вот мой xaml:

<ComboBox Name="cboParam3" Grid.Row="0" Grid.Column="5" SelectedValuePath="Key" KeyDown="headerBar_KeyDown">
   <ComboBox.ItemTemplate>
      <DataTemplate>
         <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding Path=IsSelected}" VerticalAlignment="Center" Margin="0,0,4,0" />
            <TextBlock Text="{Binding Value}" VerticalAlignment="Center"/>
         </StackPanel>
      </DataTemplate>
   </ComboBox.ItemTemplate>
</ComboBox>

А вот код, где я первоначально заполняю комбинированный список:

Dictionary<int, string> codes = CodeCache.CodeLookup<DACaseCategoryCode>();
List<MultipleComboItem> items = new List<MultipleComboItem>();

codes.ToList().ForEach(t =>
{
   MultipleComboItem item = new MultipleComboItem();

   item.Key = t.Key;
   item.Value = t.Value;
   item.IsSelected = false;

   items.Add(item);
});

this.lblParam3.Content = "Case Category:";
this.cboParam3.ItemsSource = items;

Есть ли что-то еще, что мне нужно добавить в микс, чтобы заставить это работать?

Спасибо,Sonny

PS MultipleComboItem - это простая структура с тремя свойствами.Ничего необычного там не происходит.

Ответы [ 4 ]

1 голос
/ 11 февраля 2011
<ComboBox Name="identifiercombo" Text="{Binding SelectedIdentifier, UpdateSourceTrigger=PropertyChanged}"  ItemsSource="{Binding IdentifierCollection}"  SelectedIndex="0" IsEditable="True" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Stretch" Margin="10,5">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox Click="CheckBox_Click" Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center"/>                            
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>
0 голосов
/ 01 мая 2013

Мне нужно было создать пользовательский комбинированный список флажков, чтобы представить список календарных месяцев для выбора пользователем.Это приложение позволит пользователю выбирать месяцы, и всякий раз, когда месяц выбран или не выбран, список обновляется.Я перебираю наблюдаемую коллекцию, которая является источником элементов списка, чтобы определить, какие месяцы были проверены.Вместо того, чтобы вручную перебирать наблюдаемую коллекцию, я мог бы, вероятно, использовать LINQ для запроса коллекции, но это на другой день.Если вы хотите проверить это, просто создайте новое приложение wpf под названием CustomComboBox (в C #) и скопируйте и вставьте xaml и c # в ваше приложение:

<Window x:Class="CustomComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

    </Window.Resources>
    <Grid>      
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="30"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />            
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Grid.Row="0" Content="Select the months:" />
            <Label Grid.Column="1" Grid.Row="1" Content="Months selected:" />
            <ComboBox x:Name="ComboBoxMonths" Grid.Column="0" Grid.Row="1">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox IsChecked="{Binding Path=monthSelected}" VerticalAlignment="Center" Margin="0,0,4,0" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
                            <TextBlock Text="{Binding monthName}" VerticalAlignment="Center"/>
                        </StackPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <ListBox x:Name="ListBoxMonthsChecked" Grid.Column="1" Grid.Row="2">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding monthName}" VerticalAlignment="Center"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>       
    </Grid>

</Window>

код c #:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CustomComboBox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static ObservableCollection<Month> monthList = new ObservableCollection<Month>();
        public static ObservableCollection<Month> monthsChecked = new ObservableCollection<Month>();

        public MainWindow()
        {
            InitializeComponent();

            this.ComboBoxMonths.ItemsSource = monthList;
            this.ListBoxMonthsChecked.ItemsSource = monthsChecked;

            //add Months to the ComboBoxMonths
            monthList.Add(new Month() { monthSelected = false, monthName = "January", monthNumber = 01 });
            monthList.Add(new Month() { monthSelected = false, monthName = "February", monthNumber = 02 });
            monthList.Add(new Month() { monthSelected = false, monthName = "March", monthNumber = 03 });            
            monthList.Add(new Month() { monthSelected = false, monthName = "April", monthNumber = 04 });
            monthList.Add(new Month() { monthSelected = false, monthName = "May", monthNumber = 05 });
            monthList.Add(new Month() { monthSelected = false, monthName = "June", monthNumber = 06 });
            monthList.Add(new Month() { monthSelected = false, monthName = "July", monthNumber = 07 });
            monthList.Add(new Month() { monthSelected = false, monthName = "August", monthNumber = 08 });
            monthList.Add(new Month() { monthSelected = false, monthName = "September", monthNumber = 09 });
            monthList.Add(new Month() { monthSelected = false, monthName = "October", monthNumber = 10 });
            monthList.Add(new Month() { monthSelected = false, monthName = "November", monthNumber = 11 });
            monthList.Add(new Month() { monthSelected = false, monthName = "December", monthNumber = 12 });
        }

        public class Month
        {
            public string monthName { get; set; } 
            public int monthNumber { get; set; } 

            private bool _monthSelected;
            public bool monthSelected //the checkbox is bound to this
            {
                get
                {
                    return _monthSelected;
                }
                set
                {
                    if (value != this._monthSelected)
                    {
                        _monthSelected = value;                        
                    }
                }
            }

        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            monthsChecked.Clear();
            foreach (Month m in monthList)
            {
                if (m.monthSelected == true)
                {                    
                    monthsChecked.Add(m);
                }
            }            
        }

        private void CheckBox_UnChecked(object sender, RoutedEventArgs e)
        {
            monthsChecked.Clear();
            foreach (Month m in monthList)
            {
                if (m.monthSelected == true)
                {
                    monthsChecked.Add(m);
                }
            }
        }

    }
}
0 голосов
/ 12 ноября 2010

ComboBox.SelectedItem работает правильно

Хорошо, вы можете получить выбранный MultipleComboItem.

если я перебираю все элементы, они всегда возвращают IsSelected == false.

Это связано с тем, что вы связали IsChecked = "{Binding Path = IsSelected}", если вы отметили флажок в открытом списке комбинированных списков и снова прошли по элементам, вы можете найти элемент с IsSelected == true.

Итак, если вы не установите флажок, вы не найдете IsSelected == true.

Вы должны почувствовать разницу между выбранным элементом комбинированного списка и отмеченным флажком, который представляет элемент.

0 голосов
/ 12 ноября 2010

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

Я написал приложение для быстрого тестирования, и привязка, кажется, работает нормально, используя следующее (однако, установка флажка не установит свойство SelectedItem комбобокса):

<Window x:Class="TestApp11.MainWindow" 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:l="clr-namespace:TestApp11"
  Title="Window1" >
    <Window.Resources>
    </Window.Resources>
    <Grid Background="Black">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ComboBox Name="cboParam3" Grid.Row="0" Grid.Column="0">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding Path=Select}" VerticalAlignment="Center" Margin="0,0,4,0" />
                        <TextBlock Text="{Binding Name}" VerticalAlignment="Center"/>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
            </ComboBox>
        <Button Grid.Row="1" Content="Click Me For Break Point" Click="Button_Click"></Button>
    </Grid>
</Window>


using System.Collections.ObjectModel;
using System.Windows;

namespace TestApp11
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public ObservableCollection<MCI> MCIList { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        this.MCIList = new ObservableCollection<MCI>();
        this.cboParam3.ItemsSource = this.MCIList;

        this.MCIList.Add(new MCI());
        this.MCIList.Add(new MCI());
        this.MCIList.Add(new MCI());
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {

    }

}

public class MCI
{
    public bool Select { get; set; }
    public string Name { get; set; }
    public MCI()
    {
        this.Name = "Bob";
        this.Select = false;
    }
}
}

Вы делаете что-то значительно отличающееся от того, что у меня выше?

...