WPF 包装面板如何将数据传递给用户控件
WPF wrappanel how to pass data to a usercontrol
我不是 100% 这符合整个 wpf mvvm 设计模式,但我不知道如何去做。
我在这个主视图中有一个主视图,我有一个名为 'DemoClass_List' 的 ObservableCollection,列表中的每个元素都包含一个 class 'DemoClass'.
在这个视图的 wpf 中,我有 wrappanel,我想要的是 wrappanel 为每个元素显示一个 usercontrol,但也将单独的 class 传递给元素。
代码如下。
***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,控制台崩溃
您需要在 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
。我觉得那甚至可以删除。
我不是 100% 这符合整个 wpf mvvm 设计模式,但我不知道如何去做。
我在这个主视图中有一个主视图,我有一个名为 'DemoClass_List' 的 ObservableCollection,列表中的每个元素都包含一个 class 'DemoClass'.
在这个视图的 wpf 中,我有 wrappanel,我想要的是 wrappanel 为每个元素显示一个 usercontrol,但也将单独的 class 传递给元素。
代码如下。
***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,控制台崩溃
您需要在 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
。我觉得那甚至可以删除。