Custom ComboBox triggering MouseLeave event on main window well after the fact after certain conditions met

Viewed 63

I'm new to wpf and am making a glorified app/website launcher for work. I have a MouseLeave event to shrink the window/form half a second after the mouse leaves the window, but also a MouseEnter event that either stops the shrink or restores the window upon mouse enter, kinda like autohiding the task bar in windows. I have a comboxbox under a "options" stackpanel that allows the user to change themes at runtime. Everything worked great until I added some custom combobox code that I bastardized to fit the look I wanted.

Now, only after making a selection in the combobox to change the theme, and then mousing over then leaving a menu button, it triggers the mouseleave event loop destroying any functionality.

VB.Net in Visual Studio 2015 Professional

The custom combobox style code that sits in a resource dictionary:

<Style x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToggleButton">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition Width="32" />
                        </Grid.ColumnDefinitions>
                        <Border
                          x:Name="Border"
                          Grid.ColumnSpan="2"
                          CornerRadius="3"
                          Background="{TemplateBinding Background}"
                          BorderBrush="DarkGray"
                          BorderThickness="1"/>
                        
                        <Path
                            x:Name="Arrow"
                            Grid.Column="1"    
                            Fill="Gray"
                            Stroke="Gray"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            Data="M 0 0 L 4 4 L 8 0 Z"/>
                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
        <Border x:Name="PART_ContentHost" Focusable="True" />

    </ControlTemplate>

    <Style x:Key="theComboBox" TargetType="{x:Type ComboBox}">
        <Setter Property="Foreground" Value="#333" />
        <Setter Property="BorderBrush" Value="Gray" />
        <Setter Property="Background" Value="White" />
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
        <Setter Property="FontSize" Value="13" />
        <Setter Property="MinWidth" Value="150"/>
        <Setter Property="MinHeight" Value="30"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ComboBox">
                    <Grid>
                        <ToggleButton
                            Cursor="Hand"
                            Name="ToggleButton"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Background="{TemplateBinding Background}"
                            Foreground="{TemplateBinding Foreground}"
                            Style="{StaticResource ComboBoxToggleButton}"
                            Grid.Column="2"
                            Focusable="false"
                            IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                            ClickMode="Press"/>

                        <ContentPresenter
                            Name="ContentSite"
                            IsHitTestVisible="False"
                            Content="{TemplateBinding SelectionBoxItem}"
                            ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
                            ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                            Margin="10,3,30,3"
                            VerticalAlignment="Center"
                            HorizontalAlignment="Left" />
                        <TextBox x:Name="PART_EditableTextBox"
                            Style="{x:Null}"
                            Template="{StaticResource ComboBoxTextBox}"
                            HorizontalAlignment="Left"
                            VerticalAlignment="Center"
                            Margin="3,3,23,3"
                            Focusable="True"                              
                            Visibility="Hidden"
                            IsReadOnly="{TemplateBinding IsReadOnly}"/>
                        <Popup
                            Name="Popup"
                            Placement="Bottom"
                                VerticalOffset="-3"
                            IsOpen="{TemplateBinding IsDropDownOpen}"
                            AllowsTransparency="True"
                            Focusable="False"
                            PopupAnimation="Slide">
                            <Grid
                              Name="DropDown"
                              SnapsToDevicePixels="True"              
                              MinWidth="{TemplateBinding ActualWidth}"
                              MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                <Border
                                    CornerRadius="0,0,3,3"
                                    x:Name="DropDownBorder"
                                    Background="White"
                                    BorderThickness="1"
                                    BorderBrush="DarkGray"
                                    />
                                <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                                    <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                </ScrollViewer>
                            </Grid>
                        </Popup>

                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasItems" Value="false">
                            <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                        </Trigger>
                        <Trigger Property="IsGrouping" Value="true">
                            <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                        </Trigger>
                        <Trigger Property="IsEditable" Value="true">
                            <Setter Property="IsTabStop" Value="false"/>
                            <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
                            <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
        </Style.Triggers>
    </Style>
    <Style x:Key="theComboBoxItem" TargetType="{x:Type ComboBoxItem}">
        <Setter Property="SnapsToDevicePixels" Value="true" />
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
        <Setter Property="FontSize" Value="13" />
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ComboBoxItem">
                    <Border
                        Name="Border"
                        Padding="4"
                        Margin="0"
                        BorderThickness="1"
                        CornerRadius="0"
                        Background="Transparent"
                        BorderBrush="Transparent">
                        <TextBlock TextAlignment="Left">
                            <ContentPresenter />
                        </TextBlock>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsHighlighted" Value="true">
                            <Setter TargetName="Border" Property="BorderBrush" Value="#FFE4E4E4"/>
                            <Setter TargetName="Border" Property="Background" Value="#FFE4E4E4"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

The MouseLeave/Timer/MouseEnter event handlers:

Private Sub EasiestWindow_MouseLeave(sender As Object, e As MouseEventArgs) Handles EasiestWindow.MouseLeave
        MouseLeaveTimer = New DispatcherTimer
        MouseLeaveTimer.Interval = TimeSpan.FromMilliseconds(500)
        AddHandler MouseLeaveTimer.Tick, AddressOf TickMe
        MouseLeaveTimer.Start()
        e.Handled = True
    End Sub
    Private Sub TickMe()
        SubMenu.Children.Clear()
        MainGrid.Visibility = Visibility.Collapsed
        EasiestWindow.Top = -1
    End Sub
    Private Sub EasiestWindow_MouseEnter(sender As Object, e As MouseEventArgs) Handles EasiestWindow.MouseEnter
        Try
            MouseLeaveTimer.Stop()
        Catch
        End Try
        If MainGrid.Visibility.Equals(Visibility.Visible) Then
            '****DO NOTHING****
        Else
            MainGrid.Visibility = Visibility.Visible

            If LastMenuButton Is Nothing Then
                '****DO NOTHING****
            Else
                SubMenu.Children.Clear()
                Select Case True
                    Case LastMenuButton.Equals("ProgButton")
                        For Each itemp In ButtonArrayProg
                            DescLabel.Content = "PROGRAMMING TOOLS"
                            SubMenu.Children.Add(itemp)
                        Next
                    Case LastMenuButton.Equals("ModelButton")
                        For Each itemm In ButtonArrayModel
                            SubMenu.Children.Add(itemm)
                            DescLabel.Content = "MODELING TOOLS"
                        Next
                    Case LastMenuButton.Equals("AppButton")
                        For Each itema In ButtonArrayApp
                            SubMenu.Children.Add(itema)
                            DescLabel.Content = "VARIOUS APPLICATIONS"
                        Next
                    Case LastMenuButton.Equals("WebButton")
                        For Each itemw In ButtonArrayWeb
                            SubMenu.Children.Add(itemw)
                            DescLabel.Content = "WEBSITES"
                        Next
                    Case LastMenuButton.Equals("EtcButton")
                        For Each iteme In ButtonArrayEtc
                            SubMenu.Children.Add(iteme)
                            DescLabel.Content = "EXTRANEOUS CONTENT"
                        Next
                End Select
            End If
        End If
        e.Handled = True
    End Sub

The MouseEvent handler when a menu button is entered:

Private Sub MainButton_MouseEnter(sender As Button, e As MouseEventArgs) Handles ProgButton.MouseEnter, ModelButton.MouseEnter, AppButton.MouseEnter
        DescLabel.Visibility = Visibility.Visible
        SubMenu.Children.Clear()
        LastMenuButton = sender.Name
        Select Case True
            Case sender.Name.Equals("ProgButton")
                For Each itemp In ButtonArrayProg
                    DescLabel.Content = "PROGRAMMING TOOLS"
                    SubMenu.Children.Add(itemp)
                Next
            Case sender.Name.Equals("ModelButton")
                For Each itemm In ButtonArrayModel
                    SubMenu.Children.Add(itemm)
                    DescLabel.Content = "MODELING TOOLS"
                Next
            Case sender.Name.Equals("AppButton")
                For Each itema In ButtonArrayApp
                    SubMenu.Children.Add(itema)
                    DescLabel.Content = "VARIOUS APPLICATIONS"
                Next
            Case sender.Name.Equals("WebButton")
                For Each itemw In ButtonArrayWeb
                    SubMenu.Children.Add(itemw)
                    DescLabel.Content = "WEBSITES"
                Next
            Case sender.Name.Equals("EtcButton")
                For Each iteme In ButtonArrayEtc
                    SubMenu.Children.Add(iteme)
                    DescLabel.Content = "EXTRANEOUS CONTENT"
                Next
        End Select
        e.Handled = True
    End Sub

RunTime creation of the comboxbox and settings stackpanel

    Private Sub CreateOptions()
        optionsPanel.Width = 375
        optionsPanel.Height = 150
        optionsPanel.HorizontalAlignment = HorizontalAlignment.Center
        optionsPanel.Orientation = Orientation.Vertical
        themeCombo.SetResourceReference(Control.StyleProperty, "theComboBox")
        themeCombo.Width = 150
        themeCombo.Items.Add("Default")
        themeCombo.Items.Add("Seahawks")
        themeCombo.Items.Add("Huskies")
        themeCombo.Items.Add("Cougars")
        themeCombo.Items.Add("DarkMode")
        themeCombo.Items.Add("TheBest")
        AddHandler themeCombo.SelectionChanged, AddressOf ThemeChange
        optionsPanel.Children.Add(themeCombo)
    End Sub
0 Answers
Related