设置自动生成的 ContentPresenter 的属性

发布于 2024-12-15 00:19:15 字数 1548 浏览 2 评论 0原文

考虑 Windows Phone SL 应用程序中可视化树的以下部分:

Content Presenter

如您所见,PanoramaItem 模板包含对静态 DataTemplateSelector 的引用。它是一个简单的类,可根据提供的 Key 动态提供数据模板,以显示作为 DataContextPanoramaItem 提供的不同视图模型的不同视图。这是它的代码:

public static T FindResource<T>(this DependencyObject initial, string key) where T : DependencyObject
        {
            DependencyObject current = initial;

            while (current != null)
            {
                if (current is FrameworkElement)
                {
                    if ((current as FrameworkElement).Resources.Contains(key))
                    {
                        return (T)(current as FrameworkElement).Resources[key];
                    }
                }

                current = VisualTreeHelper.GetParent(current);
            }

            if (Application.Current.Resources.Contains(key))
            {
                return (T)Application.Current.Resources[key];
            }

            return default(T);
        }
    }

    public class DataTemplateSelector : ContentControl
    {
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            ContentTemplate = this.FindResource<DataTemplate>(newContent.GetType().FullName);
        }
    }

问题是我无法控制 ContentPresenter 的创建,您可以在上面的图像中看到选中的内容。为了获得一致的布局,我需要能够设置它的垂直对齐属性。我似乎不知道如何做到这一点,因为我无法引用此 ContentPresenter。如何设置 ContentPresenter 的属性?

Consider the following part of a visual tree in a Windows Phone SL application:

Content presenter

As you can see, a PanoramaItem template contains a reference to a static DataTemplateSelector. It is a simple class that dynamically feeds the data template based on a provided Key, to display different views for different view models provided as DataContext to PanoramaItem. Here is the code for it:

public static T FindResource<T>(this DependencyObject initial, string key) where T : DependencyObject
        {
            DependencyObject current = initial;

            while (current != null)
            {
                if (current is FrameworkElement)
                {
                    if ((current as FrameworkElement).Resources.Contains(key))
                    {
                        return (T)(current as FrameworkElement).Resources[key];
                    }
                }

                current = VisualTreeHelper.GetParent(current);
            }

            if (Application.Current.Resources.Contains(key))
            {
                return (T)Application.Current.Resources[key];
            }

            return default(T);
        }
    }

    public class DataTemplateSelector : ContentControl
    {
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            ContentTemplate = this.FindResource<DataTemplate>(newContent.GetType().FullName);
        }
    }

The problem is that I have no control over the creation of ContentPresenter you can see selected on an image above. To get a consistent layout, I need to be able to set it's Vertical Alignment property. I don't seem to know how I can do it, since I can't reference this ContentPresenter. How can I set a ContentPresenter's properties?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稍尽春風 2024-12-22 00:19:15

你的面前似乎已经有了答案。

使用 VisualTreeHelper.GetParent 获取 DataTemplateSelector 的直接可视父级作为 FrameworkElement,然后修改其 VerticalAlignment财产。

顺便说一句:-

            if (current is FrameworkElement) 
            { 
                if ((current as FrameworkElement).Resources.Contains(key)) 
                { 
                    return (T)(current as FrameworkElement).Resources[key]; 
                } 
            } 

可以简化为:-

            var currentFE = current As FrameworkElement;
            if (currentFE != null && currentFE.Contains(key) )
            {
                return (T)currentFE.Resource[key];
            }

投射尝试仅发生一次,而不是可能发生三次,更短且更容易理解。添加变量是有益的示例(而通常我们可能会尝试减少代码中变量的数量)。

You seem to already have the answer sitting there in front of you.

Use the VisualTreeHelper.GetParent to get the direct visual parent of the DataTemplateSelector as a FrameworkElement, then modify its VerticalAlignment property.

BTW :-

            if (current is FrameworkElement) 
            { 
                if ((current as FrameworkElement).Resources.Contains(key)) 
                { 
                    return (T)(current as FrameworkElement).Resources[key]; 
                } 
            } 

can be reduced to:-

            var currentFE = current As FrameworkElement;
            if (currentFE != null && currentFE.Contains(key) )
            {
                return (T)currentFE.Resource[key];
            }

Cast attempt only occurs once instead of potentially three times, is shorter and is easier to understand. An example of where adding a variable is beneficial (whereas normally we might try to reduce the number of variables in our code).

牵你的手,一向走下去 2024-12-22 00:19:15

解决方案也很简单:

为我的 ContentControl 派生类定义样式:

<Style TargetType="support:DataTemplateSelector">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="support:DataTemplateSelector">
                        <ContentPresenter
                        ContentTemplate="{TemplateBinding support:DataTemplateSelector.ContentTemplate}"
                        Content="{TemplateBinding support:DataTemplateSelector.Content}" 
                        VerticalAlignment="Top"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

我在视图的 XAML 的 UserControl.Resources 部分中定义了我的样式。

在类的构造函数中调用“重新设计样式”代码行:

 public class DataTemplateSelector : ContentControl
    {
        public DataTemplateSelector()
        {
            this.DefaultStyleKey = typeof (DataTemplateSelector);
        } 

这就是您可以控制 ContentControl 派生控件的 ContentPresenter 元素外观的方式。

The solution yet again was simple:

Define a style for my ContentControl derived class:

<Style TargetType="support:DataTemplateSelector">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="support:DataTemplateSelector">
                        <ContentPresenter
                        ContentTemplate="{TemplateBinding support:DataTemplateSelector.ContentTemplate}"
                        Content="{TemplateBinding support:DataTemplateSelector.Content}" 
                        VerticalAlignment="Top"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

I have defined mine in UserControl.Resources section of a View's XAML.

The call the "restyling" line of code in the class's constructor:

 public class DataTemplateSelector : ContentControl
    {
        public DataTemplateSelector()
        {
            this.DefaultStyleKey = typeof (DataTemplateSelector);
        } 

And that's how you can control the ContentPresenter element's look of a ContentControl's derived control.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文