【问题标题】:WPF wrappanel how to pass data to a usercontrolWPF wrappanel 如何将数据传递给用户控件
【发布时间】:2016-06-28 01:56:02
【问题描述】:

我不是 100% 这与整个 wpf mvvm 设计模式一致,但我不知道该怎么做。

我在这个主视图中有一个主视图,我有一个名为“DemoClass_List”的 ObservableCollection,列表中的每个元素都包含一个类“DemoClass”。

在这个视图的 wpf 中,我有 wrappanel,我想要的是 wrappanel 为每个元素显示一个用户控件,同时也将单个类传递给元素。

代码如下。

***UserControl
public partial class DemoClass_Display : UserControl
{
    public DemoClass _demoClass;

    public DemoClass_Display()
    {
        InitialiseComponent();
        //Do processing on _demoClass and display relevant info
    }
}

***MainView WPF Snippet
<ItemsControl ItemsSource = "{Binding DemoClass_List}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <usercontrol:DemoClass_Display/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

问题是,如何填写“public DemoClass_demoClass;”项在用户控件中?

****************编辑**************** 此代码崩溃

****主视图

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public static ObservableCollection<DemoClass> DemoClass_List { get; set; }

        public Window1()
        {
            DemoClass_List = new ObservableCollection<DemoClass>();
            DemoClass dc1 = new DemoClass();
            dc1.Property1 = 1;
            dc1.Property2 = 1;
            dc1.Property3 = 1;

           DemoClass dc2 = new DemoClass();
           dc2.Property1 = 2;
           dc2.Property2 = 2;
           dc2.Property3 = 2;

           DemoClass dc3 = new DemoClass();
           dc3.Property1 = 3;
           dc3.Property2 = 3;
           dc3.Property3 = 3;

           DemoClass_List.Add(dc1);
           DemoClass_List.Add(dc2);
           DemoClass_List.Add(dc3);



           InitializeComponent();
       }
   }
}

***MainViewWPF

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:UserControl="clr-namespace:WpfApplication1"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ItemsControl ItemsSource="{Binding DemoClass_List}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                   <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
               <DataTemplate>
                    <UserControl:DemoClass_Display demoClass="{Binding}"/>
                </DataTemplate>
           </ItemsControl.ItemTemplate>
       </ItemsControl>
    </Grid>
</Window>

***用户控制

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for DemoClass_Display.xaml
    /// </summary>
    public partial class DemoClass_Display : UserControl
    {
        public static readonly DependencyProperty DemoClassProperty = DependencyProperty.Register("demoClass", typeof (DemoClass), typeof (DemoClass_Display), new PropertyMetadata(default(DemoClass)));

        public DemoClass demoClass
        {
            get { return (DemoClass)GetValue(DemoClassProperty); }
            set { SetValue(DemoClassProperty, value); }
        }

        public DemoClass_Display()
        {
            InitializeComponent();
            Console.WriteLine(demoClass.Property1);
        }
    }
}

由于没有设置 demoClass,控制台崩溃

【问题讨论】:

  • 更新了答案。添加了一个 propertychanged 处理程序。访问其中的属性。

标签: wpf mvvm binding user-controls


【解决方案1】:

你需要在你的UserControl中创建一个依赖属性:

public static readonly DependencyProperty DemoClassProperty = DependencyProperty.Register(
    "DemoClass", typeof (DemoClass), typeof (DemoClass_Display), new PropertyMetadata(default(DemoClass), OnDemoClassChanged));

public DemoClass DemoClass
{
    get { return (DemoClass) GetValue(DemoClassProperty); }
    set { SetValue(DemoClassProperty, value); }
}

private static void OnDemoClassChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    var newDemoClass = e.NewValue as DemoClass;
    var demoClassDisplay = (DemoClass_Display)dependencyObject; // you can access this UserControl this way.       

    if(newDemoClass != null)
    {
        //Do processing on newDemoClass and display relevant info
    }
}

然后就可以在DataTemplate中绑定ItemsControl的当前项了:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <usercontrol:DemoClass_Display DemoClass="{Binding}" />
    </DataTemplate>
</ItemsControl.ItemTemplate>

所以在UserControl 中,您将使用DemoClass 属性而不是字段_demoClass。我认为这甚至可以删除。

【讨论】:

  • 几乎正确。但是依赖属性应该用propertychanged处理程序声明,以便在绑定时能够处理数据。
  • 谢谢,注意到并添加到答案中。
  • 处理不能直接在静态函数中完成。我想,有必要将 dependencyObject 转换为 DemoClass_Display 并将所有处理应用于转换的引用可能并不明显。
  • 他可以访问属性的旧值和新值。他也可以访问UserControl ((DemoClass_Display)dependencyObject)。我没有看到问题......
  • 一切都完全按照我的意愿工作(除了具有约束力的问题,但认为这是一个新问题。如果我可以投票支持上述答案,我会
猜你喜欢
  • 1970-01-01
  • 2012-03-21
  • 2013-07-23
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 2014-03-10
  • 2013-10-18
  • 1970-01-01
相关资源
最近更新 更多