Чтобы отключить только 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
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.
Я могу предложить вам более простое решение, но это будет зависеть от шаблона 'ComboBox', который вы его организуете? Если да, то я могу привести пример этого в ответе. –
@ Анатолий Николаев Я всегда хочу узнать что-то новое, а затем обязательно покажу его :) –
Хорошо, дай мне время, и я покажу тебе. –