ComboBox com ItemTemplate que inclui um botão

votos
3

Então, digamos que eu tenho uma caixa de combinação com um modelo de dados personalizado. Um dos itens no modelo de dados é um botão:

<ComboBox Width=150 ItemsSource={Binding MyItems}>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <Button Content=ClickMe /> 
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

O problema com isto é que o botão come o clique, e o item não selecionado se o botão for selecionado. Isto significa que o pull-down não vai embora, e nenhum item é selecionado.

Eu entendo por que isso está acontecendo.

Existe uma maneira de contornar isso? Possivelmente uma maneira de processar o botão de clique (estou ligação a um comando) e dizer-lhe para continuar a cadeia de modo a caixa de combinação também pode processar o clique?

Nota: Eu estou vendo o meu problema no Silverlight, mas eu estou supondo que exatamente o mesmo comportamento pode ser visto com WPF.

Publicado 19/05/2009 em 17:00
fonte usuário
Em outras línguas...                            


4 respostas

votos
8

OK, eu tenho que descobri. É um corte total, mas ele ainda me permite ligar o meu comando para o botão e continuar a ter um comportamento Combo-box para selecionar o item:

<ComboBox x:Name="MyCombo" Width="150" ItemsSource="{Binding MyItems}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <Button Content="ClickMe" Click="Button_Click" /> 
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

E no código por trás:

private void Button_Click(object sender, RoutedEventArgs e)
{
    MyCombo.SelectedItem = (sender as Button).DataContext;
    MyCombo.IsDropDownOpen = false;
}

Se eu realmente quisesse, eu poderia vincular a SelectedItem e IsDropDownOpen às propriedades no meu ViewModel, mas eu decidi contra ela para manter esse comportamento como uma extensão de corte do XAML, em um esforço para manter meus ViewModel limpo.

Respondeu 20/05/2009 em 19:22
fonte usuário

votos
1

Eu encontrei outra possibilidade para o contexto MVVM. Eu usei uma classe derivada para ComboBoxe se um item está Adden que deriva do ButtonBaseque atribuo ao Clickevento para fechar a ComboBox.

Isso funciona para o meu projeto - mas apenas porque os itens em si são botões, ele não iria funcionar se eles apenas contêm botões como um elemento filho.

public class MyComboBox : ComboBox
{
    public MyComboBox()
    {
        // use Loaded event to modify inital items.
        Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        if (Items != null)
        {
            foreach (var item in Items)
            {
                var button = item as ButtonBase;
                if (button != null)
                {
                    ModifyButtonItem(button);
                }
            }
        }
    }

    protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);
        // Check added items. If an item is a button, modify the button.
        if (e.NewItems != null)
        {
            foreach (var item in e.NewItems)
            {
                var button = item as ButtonBase;
                if (button != null)
                {
                    ModifyButtonItem(button);
                }
            }
        }
    }

    private void ModifyButtonItem(ButtonBase button)
    {
        button.Click += (sender, args) => { IsDropDownOpen = false; };
    }
}
Respondeu 02/07/2012 em 12:26
fonte usuário

votos
1

Sua melhor aposta seria provavelmente para definir o SelectedItem no comando do botão.

Respondeu 20/05/2009 em 00:01
fonte usuário

votos
0

Eu não sei se existe uma maneira de fazer o que quiser. Se você tivesse que colocar um Buttonem um ListBox, por exemplo, o mesmo comportamento ocorre - clicando no Buttonnão causar seu item no ListBoxa ser selecionado. Na verdade, este é o caso de qualquer controle em uma ItemsControlque suporta seleção.

Você pode ser capaz de fazer algo com o Clickevento e marcá-lo como não tratada para que continue a árvore visual, mas mesmo assim eu não tenho certeza se isso iria funcionar ou não.

Respondeu 19/05/2009 em 17:12
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more