Domanda

Ho una casella di riepilogo in cui gli elementi contengono caselle di controllo:

<ListBox Style="{StaticResource CheckBoxListStyle}" Name="EditListBox">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Click="Checkbox_Click" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=DisplayText}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Il problema che sto riscontrando è che quando faccio clic sulla casella di controllo o sul suo contenuto, ListBoxItem padre non viene selezionato. Se faccio clic sullo spazio bianco accanto alla casella di controllo, ListBoxItem viene selezionato.

Il comportamento che sto cercando di ottenere è quello di poter selezionare uno o più elementi nell'elenco e utilizzare la barra spaziatrice per attivare e disattivare le caselle di controllo.

Altre informazioni:

private void Checkbox_Click(object sender, RoutedEventArgs e)
{
    CheckBox chkBox = e.OriginalSource as CheckBox;
}

Nel codice sopra quando faccio clic su una casella di controllo, e.Handled è falso e chkBox.Parent è null.

La risposta di Kent mi ha messo sulla strada giusta, ecco cosa ho finito con:

<ListBox Style="{StaticResource CheckBoxListStyle}" Name="EditListBox" PreviewKeyDown="ListBox_PreviewKeyDown">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" />
                <TextBlock Text="{Binding DisplayText}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Ho dovuto usare PreviewKeyDown perché per impostazione predefinita quando si preme la barra spaziatrice in una casella di riepilogo, deseleziona tutto tranne l'elemento selezionato più di recente.

È stato utile?

Soluzione

Per cominciare, metti il ??contenuto fuori dal CheckBox :

<StackPanel Orientation="Horizontal">
    <CheckBox IsChecked="{Binding IsChecked}"/>
    <TextBlock Text="{Binding DisplayText}"/>
</StackPanel>

Successivamente, dovrai assicurarti che premendo lo spazio su un ListBoxItem si verifichi il controllo del CheckBox . Esistono diversi modi per farlo, incluso un semplice gestore di eventi su ListBoxItem . Oppure potresti specificare un gestore per UIElement.KeyUp o qualsiasi altra cosa nel tuo DataTemplate :

<CheckBox IsChecked="{Binding IsChecked}" UIElement.KeyUp="..."/>

Altri suggerimenti

Puoi anche associare la proprietà IsChecked della proprietà CheckBox e IsSelected di ListBoxItem:

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding DisplayText}" IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Nel tuo caso d'uso sarebbe molto più semplice usare un ItemsControl invece di una casella di riepilogo. Un ItemsControl è simile a una casella di riepilogo, tranne per il fatto che non contiene il comportamento di selezione automatica. Ciò significa che utilizzarlo per ospitare un elenco di quelle che sono essenzialmente caselle di controllo è molto semplice e non è necessario aggirare il comportamento di selezione di ListBox.

Il semplice passaggio a ItemsControl ti darà esattamente ciò di cui hai bisogno:

<ItemsControl Style="{StaticResource CheckBoxListStyle}" Name="EditListBox">
    <ItemsControl .ItemTemplate>
        <DataTemplate>
            <CheckBox Click="Checkbox_Click" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=DisplayText}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Puoi fare clic sul testo per selezionare le caselle di controllo (comportamento predefinito) e puoi usare anche la tastiera senza dover collegare alcun gestore di eventi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top