重新打开ComboBox中的下拉列表时,TextBox不会重置焦点

时间:2017-02-20 00:47:42

标签: c# .net wpf xaml combobox

我有一个自定义的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;
    }
}

1 个答案:

答案 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。