【问题标题】:Setting ItemsPanel's properties from itemsControl从 itemsControl 设置 ItemsPanel 的属性
【发布时间】:2013-11-13 20:01:30
【问题描述】:

我正在使用自定义项控件中的自定义面板(从列表框派生的 DisplayPanelControl),样式类似于以下 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上设置属性?

【问题讨论】:

  • 您可以使用TemplateBinding,但我不清楚您的财产价值来自哪里。
  • 感谢您查看@HighCore,我的价值来自itemscontrol,而itemscontrol 又从数据绑定中获取价值。不太确定模板绑定是否会起作用,因为我也可以在 Itempanel 标记中单独设置项目面板。但会检查并通知您。
  • 嗨@HighCore,模板绑定以我上面提到的样式工作,但是当我明确设置 属性时它不起作用。
  • 如果您已经将 CustomPanel 定义为模板的一部分,则无需再次覆盖 ItemsPanelTemplate
  • @HighCore,同意,但由于它是一个项目控件,我可以在新的控件模板或样式中覆盖 ItemsPanel。并且 itemsComtrol 将开始引发异常。因此,检查 ItemsControl 中的面板类型对我来说很重要,如果它是我的自定义面板,那么我将设置所需的属性。

标签: c# wpf wpf-controls


【解决方案1】:

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

  1. 当我们通过在 Panel 上设置 IsItemsHost 属性在 itemsControls 模板中指定 Panel 时
  2. 当我们通过“ItemsPanelTemplate”标记设置项目面板时。

通过 Ian Griffiths Find Control Inside ListBox? answer 给出的解释已经解决了这个问题。

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;
    }

} 

【讨论】:

    猜你喜欢
    • 2019-03-13
    • 1970-01-01
    • 2011-04-13
    • 2010-11-18
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 2021-11-22
    相关资源
    最近更新 更多