从itemsControl设置ItemsPanel的属性

时间:2013-11-12 16:29:47

标签: c# wpf wpf-controls

我正在使用自定义Items控件中的自定义面板(DisplayPanelControl,它是从List框派生的),样式类似于以下XAML

<Style x:Key="ContainerStyle" TargetType="{x:Type local:DisplayPanelControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>                   
                    <local:CustomePanel Background="AliceBlue" IsItemsHost="True">
                    </local:CustomePanel>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

CustomePanel有一个属性Edgblending。我想通过我的Items控件设置这个属性,所以我重写了OnApplyTemplate()方法,并使用VisualTreeHelper找到我的customPanel,设置了所需的属性。

我想询问是否有更好的解决方案,通过Itemscontrol在ItemsPanel上设置属性?

1 个答案:

答案 0 :(得分:0)

这是可能在2种情况下工作的工作之一,已经在Items控件上使用了OnApplyTemplate()方法。

  1. 当我们通过在Panel
  2. 上设置IsItemsHost属性来指定itemsControls模板中的Panel时
  3. 当我们通过“ItemsPanelTemplate”标记设置Items面板时。
  4. 通过Ian Griffiths Find Control Inside ListBox?回答给出的解释来解决这个问题。

    private T GetItemsPanel<T>(ItemsControl itemsControl) where T : Panel
        {
            T _Panel = UIHelper.FindVisualChild<T>(itemsControl);
            if (_Panel == null)
            {
                ItemsPresenter itemsPresenter = UIHelper.FindVisualChild<ItemsPresenter>(itemsControl);
                if (itemsPresenter != null)
                {
                    itemsPresenter.ApplyTemplate();
                    _Panel = VisualTreeHelper.GetChild(itemsPresenter, 0) as T;
                }
            }
            return _Panel;
        }  
    

    UiHelper类的实现只不过是在可视树中找到对象并且实现如下(我已经从一些博客文章中复制了这个,但是不记得找到链接)

    public static class UIHelper
    {
        /// <summary>
        /// Finds a parent of a given item on the visual tree.
        /// </summary>
        /// <typeparam name="T">The type of the queried item.</typeparam>
        /// <param name="child">A direct or indirect child of the queried item.</param>
        /// <returns>The first parent item that matches the submitted type parameter. 
        /// If not matching item can be found, a null reference is being returned.</returns>
        public static T FindVisualParent<T>(DependencyObject child)
          where T : DependencyObject
        {
            // get parent item
            DependencyObject parentObject = VisualTreeHelper.GetParent(child);
    
            // we’ve reached the end of the tree
            if (parentObject == null) return null;
    
            // check if the parent matches the type we’re looking for
            T parent = parentObject as T;
            if (parent != null)
            {
                return parent;
            }
            else
            {
                // use recursion to proceed with next level
                return FindVisualParent<T>(parentObject);
            }
        }
        public static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
        {
            T child = default(T);
    
            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                child = v as T;
                if (child == null)
                {
                    child = FindVisualChild<T>(v);
                }
                if (child != null)
                {
                    break;
                }
            }
            return child;
        }
    
    }