The first step, an example of UI

Design pattern are very important, we will discuss MVC and MVVM a lot, but, as far as the UI is concerned, we can focus on the code behind only.

Our first step is a demo with a ComboBox.
In xaml


In code behind

    private bool IsUserVisible(FrameworkElement element, FrameworkElement container)
        if (!element.IsVisible)
            return false;

        Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
        Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
        Point TopLeft = bounds.TopLeft;
        TopLeft.Offset(0, 1E-3);
        bool ret = rect.Contains(TopLeft); 
        return ret;
    private static Point? initial_check = null;
    private Rect bounds;
    private void ComboBox_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
        if (Mouse.LeftButton == MouseButtonState.Pressed)
        if (Keyboard.IsKeyDown(Key.Down) || Keyboard.IsKeyDown(Key.Up))
        ComboBox combo = (ComboBox)sender;
        if (combo.IsDropDownOpen)
            var MousePoint = Mouse.GetPosition((ScrollViewer)e.TargetObject);
            if (initial_check != null)
                if (initial_check.Value.Equals(MousePoint))
            initial_check = MousePoint;
            int first_el = 0;
            int last_el = 0;
            bool first_found = false;
            for (int i = 0; i < combo.Items.Count; i++)
                if (IsUserVisible((FrameworkElement)(ComboBoxItem)
                    if (!first_found)
                        first_found = true;
                        first_el = i;
                    last_el = i;
            ComboBoxItem it = (ComboBoxItem)combo.ItemContainerGenerator.ContainerFromIndex(first_el); ;
            ComboBoxItem last_it = (ComboBoxItem)combo.ItemContainerGenerator.ContainerFromIndex(last_el); ;
            bounds = last_it.TransformToVisual((ScrollViewer)e.TargetObject).TransformBounds(new Rect(0.0, 0.0, last_it.ActualWidth, last_it.ActualHeight));
            if (bounds.Contains(MousePoint))
                Debug.WriteLine("ToView " + it.Content
                    + ";" + e.OriginalSource.GetType());


Why is it interesting? Good question, it shows an advanced trick to teach you a couple of things:

  1. This solution doesn’t need to manage IsKeyDown also for any other starting chars of checkbox items
  2. The check on the initial mouse position avoids a continuous loop of requests
  3. This is an original and unedited document that explains how to get access to the ScrollViewer inside the ComboBox in WPF with a very elegant code
  4. There is a clever idea to deal with the rounding in the top left point of the first item and to prevent the final ComboBox from scrolling upwards when starting with the first 3-4 items

See you soon

Please note

Let’s compare to two ways of implementing the Combo in a DataGrid.

First, a sophisticated trick to make the cell part of the visual tree.

<!—now itemssource will find the correct DataContext-->
<dg:DataGridComboBoxColumn Header="Current Product" SelectedValueBinding="{Binding Path=CurrentProduct}" SelectedValuePath="ProductID" DisplayMemberPath="ProductName">              

<Style TargetType="ComboBox">
      <Setter Property="ItemsSource" Value="{Binding Path=ProductsInCategory}" />


<Style TargetType="ComboBox">
      <Setter Property="ItemsSource" Value="{Binding Path=ProductsInCategory}" />


On the opposite hand, an easier (more standard, but static!) approach.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s