2014-01-05 10 views
4

Я хотел бы знать, как отключить ComboBox DropDown Button Programmatically. Я видел много похожих тем, но у всех из них есть решение XAML.WPF ComboBox Hide (Disable) Кнопка DropDown Programmatically

Кстати, если кто-то знает, как отключить все элементы управления ComboBox и оставить видимым только шаблон элемента, это тоже может быть полезно.

UPDATE

свое мое определение XAML

<ComboBox Name="lang_ComboBox" SelectionChanged="LanguageSelection_ComboBox_SelectionChanged"/> 

И как я использую его:

String text = "dorf"; 
BitmapImage image = new BitmapImage(new Uri("http://img88.imageshack.us/img88/4351/butchermi4.png")); 
lang_ComboBox.Width = 100; 
lang_ComboBox.Height = 30; 
Grid sp; 
for (int i = 0; i < 5; i++) 
{ 
    ColumnDefinition gridCol1 = new ColumnDefinition(); 
    gridCol1.Width = new GridLength(30.0); 
    ColumnDefinition gridCol2 = new ColumnDefinition(); 
    gridCol2.Width = new GridLength(70.0); 
    sp = new Grid() 
    { 
     Width = 100, 
     Height = 30 
    }; 
    Image im = new Image() 
    { 
     Source = image, 
     Width = 25, 
     Height = 25 
    }; 
    Label la = new Label() 
    { 
     Content = text 
    }; 
    sp.ColumnDefinitions.Add(gridCol1); 
    sp.ColumnDefinitions.Add(gridCol2); 
    Grid.SetColumn(im, 0); 
    Grid.SetColumn(la, 1); 
    sp.Children.Add(la); 
    sp.Children.Add(im); 
    lang_ComboBox.Items.Add(sp); 
} 

UPDATE 2 Хммм я получаю сейчас, я использую неверное слово. Он должен быть «Скрывать» дизайн управления и по-прежнему может выбирать из списка. Мне очень жаль. Но я знаю, как я могу это решить с Кодексом Анатолия Николаева. Чтобы скрыть дизайн управления я использую:

ToggleButton dropDownButton = GetFirstChildOfType<ToggleButton>(lang_ComboBox); 
dropDownButton.Visibility = System.Windows.Visibility.Collapsed; 

Нежелательное поведение теперь только то, что я не могу показать COMBOBOX DropDownMenu, но я буду ссылаться на него программным путем добавления на событие щелчка и должно быть хорошо.

Если есть самый простой способ сделать это, скажите мне :).

+0

Я могу предложить вам более простое решение, но это будет зависеть от шаблона 'ComboBox', который вы его организуете? Если да, то я могу привести пример этого в ответе. –

+0

@ Анатолий Николаев Я всегда хочу узнать что-то новое, а затем обязательно покажу его :) –

+0

Хорошо, дай мне время, и я покажу тебе. –

ответ

4

Чтобы отключить только ToggleButton в ComboBox программно, вам нужно найти это в контроле ComboBox с помощью VisualTreeHelper и присвоить свойство IsEnabled к ложным, как это:

XAML

<Window x:Class="DisableComboBoxButton.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" 
    Loaded="Window_Loaded"> 

    <StackPanel> 
     <ComboBox Name="comboBox" 
        Width="100" 
        Height="25" 
        SelectedIndex="0"> 

      <ComboBoxItem>Test1</ComboBoxItem> 
      <ComboBoxItem>Test2</ComboBoxItem> 
      <ComboBoxItem>Test3</ComboBoxItem> 
     </ComboBox> 

     <ComboBox Name="AllComboBoxDisabled" 
        Width="100" 
        Height="25" 
        IsEnabled="False" 
        SelectedIndex="0"> 

      <ComboBoxItem>Test1</ComboBoxItem> 
      <ComboBoxItem>Test2</ComboBoxItem> 
      <ComboBoxItem>Test3</ComboBoxItem> 
     </ComboBox> 
    </StackPanel> 
</Window> 

Code-behind

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     ToggleButton dropDownButton = GetFirstChildOfType<ToggleButton>(comboBox); 

     dropDownButton.IsEnabled = false; 
    } 

    public static T GetFirstChildOfType<T>(DependencyObject dependencyObject) where T : DependencyObject 
    { 
     if (dependencyObject == null) 
     { 
      return null; 
     } 

     for (var i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++) 
     { 
      var child = VisualTreeHelper.GetChild(dependencyObject, i); 

      var result = (child as T) ?? GetFirstChildOfType<T>(child); 

      if (result != null) 
      { 
       return result; 
      } 
     } 

     return null; 
    } 
} 

Output

enter image description here

Notes

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

Edit: another version

Не сказать, что эта версия проще в реализации, но было бы более правильным и немного проще в использовании.

Итак, нам нужен шаблон для вашего ComboBox, поскольку он позволяет получить доступ к элементам, находящимся внутри элемента управления. Точно так же ToggleButton не может быть доступен как из кода, так и из XAML.

Мы создаем свойство зависимостей присоединения, которое будет обслуживать текущее ComboBox другое свойство, например, которое даст доступ к нашей кнопке Видимость.

Наша собственность Visibility:

public static class ButtonExt 
{ 
    public static readonly DependencyProperty VisibilityProperty; 

    public static void SetVisibility(DependencyObject DepObject, Visibility value) 
    { 
     DepObject.SetValue(VisibilityProperty, value); 
    } 

    public static Visibility GetVisibility(DependencyObject DepObject) 
    { 
     return (Visibility)DepObject.GetValue(VisibilityProperty); 
    } 

    static ButtonExt() 
    { 
     PropertyMetadata VisibiltyPropertyMetadata = new PropertyMetadata(Visibility.Collapsed); 

     VisibilityProperty = DependencyProperty.RegisterAttached("Visibility", 
                  typeof(Visibility), 
                  typeof(ButtonExt), 
                  VisibiltyPropertyMetadata); 
    } 
} 

сеттер свойство в шаблоне ComboBox (пропуск версии, полная версия увидеть в проекте в App.xaml файле):

<Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type ComboBox}"> 
      <Grid> 
       <ToggleButton Name="ToggleButton" 
           Template="{StaticResource ComboBoxToggleButton}" 
           IsChecked="{Binding Path=IsDropDownOpen, 
                Mode=TwoWay, 
                RelativeSource={RelativeSource TemplatedParent}}" 
           Visibility="{TemplateBinding PropertiesExtension:ButtonExt.Visibility}" // <------ Here 
           Grid.Column="2" 
           Focusable="False"       
           ClickMode="Press" /> 

Теперь мы устанавливаем это свойство, как это :

<ComboBox Name="comboBox" 
      Style="{StaticResource ComboBoxBaseStyle}" 
      PropertiesExtension:ButtonExt.Visibility="Visible" 
      Width="100" 
      Height="30" 
      SelectedIndex="0"> 

    <ComboBoxItem>Test1</ComboBoxItem> 
    <ComboBoxItem>Test2</ComboBoxItem> 
    <ComboBoxItem>Test3</ComboBoxItem> 
</ComboBox> 

или в виде кода через Обработчики событий Click:

private void HideButton_Click(object sender, RoutedEventArgs e) 
{ 
    ButtonExt.SetVisibility(comboBox, Visibility.Hidden); 
} 

private void ShowButton_Click(object sender, RoutedEventArgs e) 
{ 
    ButtonExt.SetVisibility(comboBox, Visibility.Visible); 
}  

Полная версия примера проекта here.

+0

@Tunczyk: См. Мое редактирование. –

+0

Nokolaev благодарит человека :) –