我有一个自定义的ComboBox来处理文本输入并过滤itemsource。我遇到的问题是,当我打开ComboBox时,textBox被聚焦并让我在其中写入,然后如果我关闭并再次打开它,TextBox没有聚焦,我不能在里面写任何东西。我发现第一次打开comboBox时,它将焦点设置在TextBox上,但当我关闭它时,TextBox保持其IsFocused
属性为true,因此重新打开问题时会发生。它只是在打开并重新打开时单击comboBox,因为如果我在ComboBox外部单击以关闭它然后再打开它一切都很好。
这是我写的自定义样式和我使用的ComboBox。
<Style x:Key="FilteringComboBox" TargetType="ComboBox">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="IsEditable" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="FontFamily" Value="Coves"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Border x:Name="TopBorder"
CornerRadius="8"
BorderBrush="Grey"
BorderThickness="1"
Padding="10,0,1,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.504,1.5" StartPoint="0.504,0.03">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#e3e3e5" Offset="0.65"/>
</LinearGradientBrush>
</Border.Background>
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{DynamicResource FilteringComboBoxToggleButton}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<TextBlock Name="ContentSite" IsHitTestVisible="False"
Text="{Binding Source={StaticResource Proxy}, Path=Data.Name, UpdateSourceTrigger=PropertyChanged}"
Visibility="Visible" Foreground="#37465c"
Padding="3,3,23,3" VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox" MaxWidth="215" MinWidth="100"
Text="{Binding Source={StaticResource Proxy}, Path=Data.FilterText, UpdateSourceTrigger=PropertyChanged}"
Foreground="#37465c"
HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Focusable="True" Background="Transparent"
Visibility="Collapsed"/>
<Popup x:Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True"
Focusable="False" PopupAnimation="Fade">
<StackPanel Orientation="Vertical" Width="215">
<Grid Name="DropDown" SnapsToDevicePixels="True"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" BorderThickness="1"
BorderBrush="#888">
<Border.Background>
<LinearGradientBrush EndPoint="0.504,1.5" StartPoint="0.504,0.03">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#e3e3e5" Offset="0.65"/>
</LinearGradientBrush>
</Border.Background>
<ScrollViewer Margin="0" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
</ScrollViewer>
</Border>
</Grid>
</StackPanel>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsDropDownOpen" Value="True"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Collapsed" />
<Setter Property="IsEditable" Value="True"/>
</Trigger>
<Trigger Property="IsMouseCaptured" Value="False">
<Setter Property="IsDropDownOpen" Value="False"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Visible" />
<Setter Property="Text" Value=""/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我尝试添加此事件处理程序以移除焦点,但它不起作用
private static void QuantityBox_IsMouseCapturedWithin(object sender, DependencyPropertyChangedEventArgs e)
{
var qBox = sender as ComboBox;
if (qBox.IsDropDownOpen == false)
{
Keyboard.ClearFocus();
flag = true;
}
}
答案 0 :(得分:0)
希望这有助于某人,因为我正在使用这些触发器而发生了不稳定的行为:
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsDropDownOpen" Value="True"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Collapsed" />
<Setter Property="IsEditable" Value="True"/>
</Trigger>
<Trigger Property="IsMouseCaptured" Value="False">
<Setter Property="IsDropDownOpen" Value="False"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Visible" />
<Setter Property="Text" Value=""/>
</Trigger>
触发器用于处理TexBlock和TextBox之间的可见性切换(在ComboBox处于非活动状态时显示TextBlock,在聚焦时显示TextBox,以便用户可以键入和过滤)。 所以我删除了触发器并在依赖属性中处理了这种行为:
public static readonly DependencyProperty MouseCapturedProperty = DependencyProperty.RegisterAttached("MouseCaptured",
typeof(bool), typeof(QuantitiesBoxBehaviours),
new UIPropertyMetadata(false, MouseCapturedPropertyChangedCallback));
public static bool GetMouseCaptured(UIElement element)
{
return (bool)element.GetValue(MouseCapturedProperty);
}
public static void SetMouseCaptured(UIElement element, bool command)
{
element.SetValue(MouseCapturedProperty, command);
}
private static void MouseCapturedPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var qBox = d as ComboBox;
bool value = GetMouseCaptured(qBox);
if (qBox != null && value)
{
qBox.IsMouseCaptureWithinChanged += QBox_IsMouseCaptureWithinChanged;
qBox.DropDownOpened += QBox_DropDownOpened;
}
}
private static void QBox_DropDownOpened(object sender, EventArgs e)
{
var qBox = sender as ComboBox;
var template = qBox.Template;
var txtBox = template.FindName("PART_EditableTextBox", qBox) as TextBox;
var txtBlock = template.FindName("ContentSite", qBox) as TextBlock;
txtBlock.Visibility = Visibility.Collapsed;
txtBox.Visibility = Visibility.Visible;
}
private static void QBox_IsMouseCaptureWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var qBox = sender as ComboBox;
var template = qBox.Template;
var txtBox = template.FindName("PART_EditableTextBox", qBox) as TextBox;
var txtBlock = template.FindName("ContentSite", qBox) as TextBlock;
if (qBox.IsDropDownOpen == false)
{
Keyboard.ClearFocus();
txtBox.Visibility = Visibility.Collapsed;
txtBlock.Visibility = Visibility.Visible;
qBox.ItemsSource = _presentationQuantities;
flag = true;
}
}
这解决了问题,现在它工作得很好,该属性设置为ComboBox。