Как получить ширину всплывающих окон в шаблоне ComboBox

1

У меня есть IMultiValueConverter, что я хотел бы выяснить ширину ComboBox, когда он перечислит значения.

Я посмотрел шаблон MSDN ComboBox и вижу, что есть всплывающее окно с x: Name = "Popup", на самом деле это немного запутывает в верхней части страницы, которую они называют PART_Popup. Ссылка MSDN

Как я могу получить объект Popup, чтобы определить его ширину? Если всплывающее окно не является вариантом по какой-либо причине, то о сетке, которая находится внутри него.

Я видел, что другие раньше повторяли все элементы, которые искали максимальную длину в текстовом рендеринге, я хотел бы попробовать, если это возможно, по возможности.

public class ComboBoxWidthConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double cbxWidth = 100;

        if (values[0] == null || values[1] == null)
            return cbxWidth;

        ComboBox cb = (ComboBox)values[0];

        int itemCount = (int)values[1];

        if (itemCount == 0)
            return cbxWidth;

        //Find popup and retrieve width.

        return cbxWidth;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  • 0
    Я думаю, что сначала вы должны вызвать cb.IsOpen = "True", а затем искать ребенка, но я не уверен, что он находится в дереве Visual .. Я бы связал его в шаблоне cb с некоторым элементом, на который я не могу ссылаться как ребенок, как кр.
  • 0
    Я почти уверен, что это неправильное использование Конвертера, возможно, если бы вы могли уточнить, почему вам нужно получить ширину всплывающего окна, может быть лучшее решение для этого. Обычно в WPF, если вы не можете сделать что-то прямое (например, получить доступ к элементу Popup ComboBox ), вы пытаетесь сделать что-то не так.
Показать ещё 11 комментариев
Теги:
wpf

1 ответ

0
Лучший ответ

Это работает: вы можете подумать о том, как интегрировать его в свой конвертер.

  void MainWindow_Loaded(object sender, RoutedEventArgs e)
  {
       // comboBox is an element in 'MainWindow'
       var popup = VisualTreeHelperExtensions.FindVisualChild<Popup>(comboBox);
  }

  public static T FindVisualChild<T>(DependencyObject depObj) where T : Visual
    {
        if (depObj != null && IsVisual(depObj))
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);

                if (child != null && child is T)
                {
                    return (T)child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    return childOfChild;
                }
            }
        }
        return null;
    }    

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj == null)
            yield break;

        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            if (IsVisual(depObj))
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);

                if (child != null && child is T)
                {
                    yield return (T) child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

    private static bool IsVisual(DependencyObject depObj)
    {
        return depObj is Visual || depObj is Visual3D;
    }
  • 0
    IsVisual () не распознается
  • 0
    и FindVisualChildren ()
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню