首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在EventHandler中处理错误的ComboBox.ItemContainerGenerator.Status?

如何在EventHandler中处理错误的ComboBox.ItemContainerGenerator.Status?
EN

Stack Overflow用户
提问于 2017-08-17 16:30:16
回答 1查看 231关注 0票数 1

我正在使用一个组合框,它从How can I make a WPF combo box have the width of its widest element in XAML?中附加的行为答案(目前是46个向上投票)中描述的最宽元素中获取宽度

代码语言:javascript
复制
public static void SetWidthFromItems(this ComboBox comboBox)
{
    double comboBoxWidth = 19;// comboBox.DesiredSize.Width;

    // Create the peer and provider to expand the comboBox in code behind. 
    ComboBoxAutomationPeer peer = new ComboBoxAutomationPeer(comboBox);
    IExpandCollapseProvider provider = (IExpandCollapseProvider)peer.GetPattern(PatternInterface.ExpandCollapse);
    EventHandler eventHandler = null;
    eventHandler = new EventHandler(delegate
    {
        if (comboBox.IsDropDownOpen &&
            comboBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
        {
            double width = 0;
            foreach (var item in comboBox.Items)
            {
                 var container = comboBox.ItemContainerGenerator.ContainerFromItem(item);
                 if (container is ComboBoxItem)
                 {
                     var comboBoxItem = (ComboBoxItem) container;
                     comboBoxItem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                     if (comboBoxItem.DesiredSize.Width > width)
                     {
                         width = comboBoxItem.DesiredSize.Width;
                     }
                 }
                 else
                 {
                    /* FIXME: coming here means that for some reason ComboBoxItems */ 
                    /* are not generated even if comboBox.ItemContainerGenerator.Status seems to be OK  */
                    return;
                 }                
            }
            comboBox.Width = comboBoxWidth + width;
            // Remove the event handler. 
            comboBox.ItemContainerGenerator.StatusChanged -= eventHandler;
            comboBox.DropDownOpened -= eventHandler;
            provider.Collapse();
        }
    });
    comboBox.ItemContainerGenerator.StatusChanged += eventHandler;
    comboBox.DropDownOpened += eventHandler;
    // Expand the comboBox to generate all its ComboBoxItem's. 
    provider.Expand();
}

但是,当在win10中动态缩放文本大小时,该解决方案不起作用。问题是,即使条件是

代码语言:javascript
复制
comboBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated

为真,则调用

代码语言:javascript
复制
comboBox.ItemContainerGenerator.ContainerFromItem(item); 

从看似ok的项返回null。

所以我的问题是:我应该如何修改代码,以确保宽度计算正确?我问这个是因为我没有win10,不能复制和玩耍。我得请一个同事来测试一下。

我试着删除行

代码语言:javascript
复制
comboBox.ItemContainerGenerator.StatusChanged -= eventHandler;

这导致在用鼠标单击窄的组合框时测量到正确的宽度。因此,一种解决方案是以某种方式强制在某个地方引发StatusChanged事件。

EN

回答 1

Stack Overflow用户

发布于 2017-08-17 21:00:55

我想出了一个解决方案,那就是远非完美的 up a worka round。测量只需要做一次,因为我不会在ComboBox准备好后添加项目。所以我记录了测量的ComboBoxes:

代码语言:javascript
复制
    private static HashSet<string> _measuredWidthNamesSet = new HashSet<string>();
    private static void OnComboBoxLoaded(object sender, RoutedEventArgs e)
    {
        ComboBox comboBox = sender as ComboBox;
        if (!_measuredWidthNamesSet.Contains(comboBox.Name))
        {
            Action action = () => { comboBox.SetWidthFromItems(_measuredWidthNamesSet); };
            comboBox.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
        }
    }

如果comboBox.ItemContainerGenerator.ContainerFromItem(item)返回null,我们不会检查宽度,也不会将ComboBox名称添加到度量的ComboBoxes集合中:

代码语言:javascript
复制
    public static void SetWidthFromItems(this ComboBox comboBox, HashSet<string> measuredWidthNamesSet)
    {
        double comboBoxWidth = 19;// comboBox.DesiredSize.Width;

        // Create the peer and provider to expand the comboBox in code behind. 
        ComboBoxAutomationPeer peer = new ComboBoxAutomationPeer(comboBox);
        IExpandCollapseProvider provider = (IExpandCollapseProvider)peer.GetPattern(PatternInterface.ExpandCollapse);
        EventHandler eventHandler = null;
        eventHandler = new EventHandler(delegate
        {
            if (comboBox.IsDropDownOpen &&
                comboBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
            {
                bool isSuccess = true;
                double width = 0;
                foreach (var item in comboBox.Items)
                {
                    var container = comboBox.ItemContainerGenerator.ContainerFromItem(item);
                    if (container is ComboBoxItem)
                    {
                        var comboBoxItem = (ComboBoxItem) container;
                        comboBoxItem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                        if (comboBoxItem.DesiredSize.Width > width)
                        {
                            width = comboBoxItem.DesiredSize.Width;
                        }
                    }
                    else
                    {
                        /* coming here means that for some reason ComboBoxItems are not generated even if
                         * comboBox.ItemContainerGenerator.Status seems to be OK */
                        isSuccess = false;
                        break;
                    }
                }
                if (isSuccess)
                {
                    comboBox.Width = comboBoxWidth + width;
                    measuredWidthNamesSet.Add(comboBox.Name);
                }

                // Remove the event handler. 
                comboBox.ItemContainerGenerator.StatusChanged -= eventHandler;
                comboBox.DropDownOpened -= eventHandler;
                provider.Collapse();
            }
        });
        comboBox.ItemContainerGenerator.StatusChanged += eventHandler;
        comboBox.DropDownOpened += eventHandler;
        // Expand the comboBox to generate all its ComboBoxItem's. 
        provider.Expand();
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45730146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档