以编程方式从DataTemplate访问控件 [英] Programmatically access a control from a DataTemplate

查看:86
本文介绍了以编程方式从DataTemplate访问控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在DataTemplate中获得控件的好方法是什么?我使用了将Loaded事件处理到感兴趣的控件上的技术,以及使用VisualTreeHelper遍历可视化树的方法,这些方法都不是很优雅。什么是访问DataTemplate控件的好方法?

What's a good way to get at the controls in a DataTemplate? I've used the technique of handing the Loaded event on the control of interest as well as using VisualTreeHelper to walk the visual tree and neither of those is very elegant. What's a good way to access DataTemplate controls?

在一个示例中,我需要添加一个绑定,在设计时不知道谁是ConverterParameter,并且由于绑定到ConverterParameters是未知的不支持,我需要在代码中创建绑定。理想情况下,我希望能够在数据模板中控件的Loaded事件处理程序之外的其他地方执行此操作。

In one example, I need to add a binding whos ConverterParameter isn't know at design time, and since binding to ConverterParameters isn't supported I need to create the binding in code. Ideally I'd like to be able to do this somewhere other than the Loaded event hander for the control in the datatemplate.

实际上,在这种情况下,处理事件不会根本无法工作,并导致OutOfMemoryException。这是我的尝试:

In fact, in this scenario handling events doesn't work at all and causes the an OutOfMemoryException. Here's my attempt:

generic.xaml:

generic.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SilverlightTest">


    <Style TargetType="local:TemplatedControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:TemplatedControl">
                    <ListBox ItemsSource="{TemplateBinding ListBoxItemsSource}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock x:Name="SomeTextBlock"
                                    Loaded="SomeTextBlock_Loaded"/>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

templatedcontrol.cs:

templatedcontrol.cs:

public class TemplatedControl : Control
    {
        public object ListBoxItemsSource
        {
            get { return (object)GetValue(ListBoxItemsSourceProperty); }
            set { SetValue(ListBoxItemsSourceProperty, value); }
        }

        public static readonly DependencyProperty ListBoxItemsSourceProperty =
            DependencyProperty.Register
            ("ListBoxItemsSource", typeof(object),
             typeof(TemplatedControl), new PropertyMetadata(null));

        public TemplatedControl()
        {
            this.DefaultStyleKey = typeof(TemplatedControl);
        }

        public void SomeTextBlock_Loaded(object sender, RoutedEventArgs ea)
        {
        }
    }


推荐答案

您可以在DataTemplate中使用另一个控件来处理此问题,但也需要注意除非您真的相信逻辑是合理的。。

You could have another control in your DataTemplate to handle that, but that's kind of messy also with the caveat of "unless you really believe the logic justifies it".

您可能想重新考虑您的方法。在我看来(这只是一种意见!),应该只在更多的 exotic 情况下将其绑定在代码中。

You might want to rethink your approach. In my opinion (and it's just an opinion!), one should only be binding in code in more exotic situations.

也许不要使用IValueConverter,绑定到ViewModel的属性(假设ItemsSource是ViewModels的集合),然后让您的VM相应地转换您的值。让此控件的默认样式通用且难看,并在需要绑定到特定属性的情况下使用特定样式。

Maybe instead of using a IValueConverter, bind to a property on the a ViewModel (assuming your ItemsSource is a collection of ViewModels), and let your VM convert your values accordingly. Let your default style for this control be generic and ugly and maybe use specific styles for cases when you need to bind to specific properties.

这篇关于以编程方式从DataTemplate访问控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆