如何获取 ComboBox 模板中 Popup 的宽度
How to get width of Popup thats in the ComboBox template
我有这个 IMultiValueConverter,我想在它列出更改值时计算出 ComboBox 的宽度。
我查看了 MSDN ComboBox 模板,可以看到有一个 Popup,带有 x:Name="Popup",实际上在页面顶部他们称之为有点混乱PART_Popup。 MSDN link
如何获取 Popup 对象以确定其宽度?如果出于某种原因无法选择 Popup,那么其中的 Grid 又如何呢。
之前看到别人遍历所有项寻找文本渲染的最大长度,如果可能的话我想试试这个方法。
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();
}
}
这行得通:您可能会想办法将它集成到您的 Converter 中。
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;
}
我有这个 IMultiValueConverter,我想在它列出更改值时计算出 ComboBox 的宽度。
我查看了 MSDN ComboBox 模板,可以看到有一个 Popup,带有 x:Name="Popup",实际上在页面顶部他们称之为有点混乱PART_Popup。 MSDN link
如何获取 Popup 对象以确定其宽度?如果出于某种原因无法选择 Popup,那么其中的 Grid 又如何呢。
之前看到别人遍历所有项寻找文本渲染的最大长度,如果可能的话我想试试这个方法。
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();
}
}
这行得通:您可能会想办法将它集成到您的 Converter 中。
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;
}