WPF – Combobox di Caselle di controllo – Associazione IsSelected?

Ho implementato un controllo ComboBox di Caselle di controllo che sembra piuttosto buono nell’interfaccia grafica, ma sto avendo problemi a usarlo in maniera funzionale.

Il principale problema che sto avendo è capire che le scatole sono effettivamente controllato. In fase di runtime, il controllo ComboBox.SelectedItem funziona correttamente, ma se devo scorrere tutti gli elementi, sono sempre tornare IsSelected == false.

Tutte le idee?

Ecco il mio codice 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>

E qui c’è il codice dove ho iniziato a popolare la 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;

C’è qualcos’altro che devo aggiungere al mix di ottenere questo lavoro?

Grazie,
Sonny

PS MultipleComboItem è solo una semplice struttura con tre proprietà. Niente accadendo.

InformationsquelleAutor Sonny Boy | 2010-11-12

 

4 Replies
  1. 0

    EDIT:

    Ho scritto una rapida applicazione di test e l’associazione sembra funzionare bene utilizzando il seguente (tuttavia, il controllo di una casella di controllo non combobox proprietà 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;
        }
    }
    }

    Stai facendo qualcosa di significativamente diverso rispetto a quello che ho sopra?

    • Nessuna differenza quando cambio il nome della proprietà.
    • Ho modificato la mia soluzione per mostrare un rapido esempio di progetto che si lega in modo corretto. Sembra che ciò che hai dovrebbe associare la proprietà correttamente… ma non credo clic sulla casella di controllo deve impostare la combobox.selezionate la voce proprietà. Nell’esempio che ho fornito qui sopra. Fare clic su un elemento della casella di controllo produce risultati diversi rispetto clic sul testo “Bob”. (l’ultimo set il cboParam3.selecteditem, semplicemente facendo clic su una casella per aggiornare l’Selezionare proprietà di MCI oggetto, ma non il cboParam3.Proprietà SelectedItem. Spero che questo aiuta!
    • Dato che io possa controllare più di una casella di controllo, come posso ottenere la moltiplicare gli elementi selezionati? Il ItemSource della lista contiene tutte le mie MCIs, ma la proprietà Selezionata non sembra di avere impostato a true o false quando io seleziona una delle caselle di controllo…
    • Se si utilizza il codice che ho postato sopra in un nuovo progetto… non hai ancora il problema? Sembra funzionare e impostare la proprietà Selezionata correttamente per me. Il motivo che mi chiedo è mi chiedo se c’è qualcosa nel codice che consente di reimpostare la proprietà itemssource, o reinizializza il tuo Elenco<MultipleComboItem> elementi oggetto///
    • Scott, sì. Ho resettato la ItemSource più volte durante il runtime. La mia Combobox fornisce un set di parametri che utilizza all’interno di un report e lo schermo stesso è utilizzato per più rapporti, e quindi i parametri cambiano a seconda di quale rapporto sta mostrando.
    • INFINE il lavoro. Una volta che ho tolto il SelectedValuePath dal ComboBox stesso, ItemsSource funzionato come previsto.
    • Un’altra cosa così… per qualsiasi motivo sembra funzionare solo se faccio MCI una classe. Non funziona come una struttura.

  2. 1
    <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>
  3. 0

    ComboBox.SelectedItem funziona correttamente

    Ok, si può ottenere selezionato MultipleComboItem.

    se ho iterare su tutti gli elementi, sono sempre tornare IsSelected == false.

    È perché hai associato IsChecked=”{Binding Path=IsSelected}”, se si spunta la casella di controllo in apertura a elenco di controllo combobox e scorrere gli elementi di nuovo si può trovare l’elemento con IsSelected == true.

    Così, se non controllare la casella di controllo non trovi IsSelected == true.

    Devi sentire la differenza tra selezionato elemento di controllo combobox e controllato casella di controllo che presenta la voce.

    • Sì. Io non sono interessato con il SelectedItem della ComboBox. Ho bisogno di trovare Caselle di controllo siano selezionate. Stavo cercando di dire, allora, quando posso controllare il SelectedItem (che è uno dei MultipleComboItems) si mostra correttamente la proprietà Selezionata. Quando ho scorrere tutte le ComboBox.Le voci, però, nessuno sembra essere selezionato.
  4. 0

    Ho bisogno di creare un custom combobox di caselle di controllo per presentare una lista di mesi di calendario per l’utente di scegliere. Questa applicazione consente all’utente di selezionare i mesi e ogni qualvolta il mese selezionato o deselezionato, una casella di riepilogo viene aggiornato. Ho scorrere la raccolta osservabile che è il itemsource della combobox per determinare in quali mesi sono stati controllati. Invece di manualmente l’iterazione attraverso la raccolta osservabile, probabilmente potrei utilizzare LINQ to query collezione, ma che è per un altro giorno. Se volete provare, basta creare una nuova applicazione wpf chiamato CustomComboBox (in C#) e copiare e incollare il codice xaml e c# nella tua app:

    <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>

    il codice 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);
                    }
                }
            }
    
        }
    }

Lascia un commento