【问题标题】:Access items inside the DataTemplate in WPF在 WPF 中访问 DataTemplate 内的项目
【发布时间】:2009-10-15 21:49:02
【问题描述】:

我想知道在 WPF 中是否能够获取数据模板对象的实际实例。例如以下情况:

<UserControl>
    <UserControl.Resources>
        <DataTemplate x:Key="MyTemplate">
            <CustomControl ></CustomControl>
        </DataTemplate>
    </UserControl.Resources>

    <ListBox DataTemplate="{StaticResource MyTemplate}"></ListBox>
</UserControl>

假设CustomControl 有一个CustomEvent 和一个公共CustomMethod。我想访问该事件和用户控件中的公共方法。这可能吗?我怎么能做到这一点?提前感谢您的帮助。

干杯,

尼禄

【问题讨论】:

  • @itowlson:来自放置 ListBox 的用户控件。我想在事件触发时从用户控件调用自定义方法(包含在 CustomControl 中)。

标签: wpf datatemplate


【解决方案1】:

您需要找到保存 ListBox 的 ContentPresenter(通过导航 VisualTree),然后使用

myDataTemplate.FindName("myCustomControl", myListBox);

MSDN上有一个例子:http://msdn.microsoft.com/en-us/library/bb613579.aspx

【讨论】:

  • 通过 VisualTree 通常不是您想要的,并且对于这种情况存在更好的解决方案
  • 我回答了“[如何] 获取数据模板对象的实际实例”的问题。毕竟,问题标题是“在 WPF 中访问 DataTemplate 中的项目”。据我所知,这是执行此操作的标准方法。
  • 投票赞成这个答案,因为这是我发现这个问题时正在寻找的答案。这可能不是最好的方法,提供替代方案也不错,但这没有理由拒绝对所提出问题的明显正确答案投反对票。
【解决方案2】:

您可以创建一个附加到 CustomControl 并与之交互的对象。

这里的这篇博文说明了一些我们可以扩展的有用概念:ICommand for Silverlight with Attached Behaviors

因此,您可以创建一个附加到自定义控件的类,而不是附加到按钮的单击事件(在 WPF 中已经有一个命令)。

按照引用的博客文章中的模式,您最终会得到:

<CustomControl 
  MyNamespace:CustomControlCommand.EventCommand=
  "{Binding Path=CommandHandler}" />

这将使您可以通过将 CustomControl 的事件转换为命令来访问它们。

【讨论】:

    【解决方案3】:

    我没有在 ListBox 上看到 ItemsSource 数据绑定,所以我假设您忽略了它。如果你绑定到 ObservableCollection 之类的东西,那么 ListBox 中的每个项目都会有它自己的 ViewModel 类。您可以根据自己的喜好对它们使用公共方法。

    如果您希望处理自定义控件中的事件,请在最低级别的代码隐藏中处理它,在这种情况下,在 UserControl 的代码隐藏中。

    然后,在每个 ViewModel 中都有一个 ICommand 实例(如果适合您的目的,也可以是一个路由命令)。在 UserControl 中,您有一个 DataContext,您可以将其转换为 ViewModel 的类型。因此事件处理程序可以访问 ViewModel 并执行命令。

    这里是Josh Smith's article on Routed Commands,您可能会觉得有趣

    Apps with MVVM architecture 上的这篇文章中,Josh 描述了自定义 ICommands

    (这是伪代码)

    class ViewModelType {
        public void DoSomething() { /* ... */ }
        public ICommand DoSomethingCommand { get; set; }
        public string Property { get; set; }
    }
    
    class CodeBehind {
        public void EventHandler(object, args) {
            (DataContext as ViewModelType).DoSomethingElseCommand.Execute();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-26
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      相关资源
      最近更新 更多