【问题标题】:Implement DataTemplate DependencyProperty in UserControl在 UserControl 中实现 DataTemplate DependencyProperty
【发布时间】:2011-09-23 13:13:01
【问题描述】:

我正在尝试使用 Expression Blend 4 在 Silverlight 4 中的 UserControl 中创建一个 intertia 触摸滚动列表。我已经在我的 UserControl 中创建了依赖属性,我想像 ListBox 一样工作。 ItemSource 是我想在我的列表中显示的对象列表,而 datatemplate 是它应该显示的方式。

如何在我的 UserControl 中处理这些属性?我有一个 StackPanel,应该在其中添加所有数据模板,以显示 c 的数据。

当循环通过 ItemSource 以将它们添加到列表 (StackPanel) 时,如何将 IEnumerable 中的数据应用到 DataTemplate。

        public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(InertiaScrollBox), null); 
    public IEnumerable ItemsSource
    {
        get{ return (IEnumerable)GetValue(ItemsSourceProperty); }
        set{ SetValue(ItemsSourceProperty, value); }
    }

    public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(InertiaScrollBox), null);
    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }

这有点难以解释,但希望您能理解,否则请询问。提前致谢

【问题讨论】:

  • 似乎您最好将 ListBox 子类化或使用行为。通常依赖属性用于 Control 而不是 UserControl。
  • 使用控件模板或继承现有控件可能会更好,但我们并不了解所有细节,问题是关于数据模板。
  • 我正在创建一个触摸惯性滚动列表。子类化 ListBox 使我很难捕捉到所有鼠标事件,因为默认情况下,鼠标左键被 ListBox 内的 ListBoxItem 控件捕捉到。也许可以做到,但我认为它会比我现在得到的更复杂,效果很好:)

标签: silverlight user-controls datatemplate dependency-properties


【解决方案1】:

如果不处理它们的更改,依赖属性将毫无用处。 首先,您应该添加 PropertyChanged 回调。在我的示例中,我将它们内联并调用 UpdateItems 私有方法。

public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(InertiaScrollBox), 
    new PropertyMetadata((s, e) => ((InertiaScrollBox)s).UpdateItems()));

public static readonly DependencyProperty ItemTemplateProperty = 
DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(InertiaScrollBox), 
    new PropertyMetadata((s, e) => ((InertiaScrollBox)s).UpdateItems()));

然后您可以调用DataTemplate 类的LoadContent 方法并将ItemsSource 中的一个项目作为DataContext 设置为返回的可视元素:

private void UpdateItems()
{
    //Actually it is possible to use only the ItemsSource property,
    //but I would rather wait until both properties are set
    if(this.ItemsSource == null || this.ItemTemplate == null)
        return;

    foreach (var item in this.ItemsSource)
    {
        var visualItem = this.ItemTemplate.LoadContent() as FrameworkElement;
        if(visualItem != null)
        {
            visualItem.DataContext = item;
            //Add the visualItem object to a list or StackPanel
            //...
        }
    }
}

【讨论】:

  • 我昨天确实想通了,但还没有时间填写答案。这与我的做法非常接近。实际上它有点简单,因为我有单独的处理程序,这在我的情况下是不必要的。非常感谢!
猜你喜欢
  • 2012-03-02
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
  • 2017-02-18
  • 2018-11-23
  • 1970-01-01
相关资源
最近更新 更多