C# 将模型中的数据对象集合绑定到视图中的一组控件(WPF)
另一个WPF问题来自我这里 我目前的情况是,我需要将模型中数据对象的C# 将模型中的数据对象集合绑定到视图中的一组控件(WPF),c#,wpf,data-binding,collections,wpf-controls,C#,Wpf,Data Binding,Collections,Wpf Controls,另一个WPF问题来自我这里 我目前的情况是,我需要将模型中数据对象的可观测集合绑定到视图中的一组用户控件。数据对象的数量经常变化,随着集合的变化,我需要动态创建这些UserControls。当前代码如下所示: private void viewModel_PropertyChanged( object sender, PropertyChangedEventArgs e ) { if( e.PropertyName.Equals( "SomeCollection" ) ) {
可观测集合
绑定到视图中的一组用户控件。数据对象的数量经常变化,随着集合的变化,我需要动态创建这些UserControls。当前代码如下所示:
private void viewModel_PropertyChanged( object sender, PropertyChangedEventArgs e )
{
if( e.PropertyName.Equals( "SomeCollection" ) )
{
UpdateUI();
}
}
private void UpdateUI()
{
foreach( MyUserControl elem in _uiElements )
{
elem.MouseLeftButtonDown -= elem_MouseLeftButtonDown;
// more event handler unhooking
_MyCanvas.Children.Remove( elem );
}
_uiElements.Clear();
foreach( DataObj dataObj in ViewModel.DataObjects )
{
MyUserControl newElem = new MyUserControl();
_uiElements.Add( newElem );
fpv.MouseLeftButtonDown += fpv_MouseLeftButtonDown;
// more event handler hookups
newElem.DataObject = dataObj;
_MyCanvas.Children.Add( newElem );
Point dest = dataObj.ScreenPoint;
Canvas.SetLeft( newElem, dest.X );
Canvas.SetTop( newElem, dest.Y );
}
}
因此,如您所见,我(在代码中)响应更改的属性,并动态创建一组新的UserControl。当“移动”(包含点特性)、添加、创建或设置整个集合时,将调用此代码。问题是,这可能需要一秒钟或更长时间(100+个元素的最坏情况),这是不可接受的。控制本身很简单;只有一个网格和一个形状(椭圆)
TLDR
所以,我想我是在问是否有人遇到过类似的情况。动态创建控件以响应集合中的更改,并从UI中添加/删除控件,类似于ItemsSource属性在ComboBox、ListBox、DataGrid等中的工作方式。关键是这些控件需要允许鼠标拖动,并在画布中的任意位置布置区域。感谢您的帮助。为什么不使用带有ItemTemplateSelector的虚拟化Items控件?如果控件很简单,那么应该可以为它们使用数据模板,因此无需创建用户控件。由于items控件是虚拟化的,因此只会呈现可见的项目,因此应该更快。这正是items控件的用途,但是当您需要使用画布并从数据中提取位置时,布局会出现一些褶皱。这并不复杂,但需要几个不同的部分才能正常工作。假设您的ViewModel是DataContext,下面是一个快速示例:
<ItemsControl ItemsSource="{Binding DataObjects}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.ScreenPoint.X}" />
<Setter Property="Canvas.Top" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.ScreenPoint.Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- your UserControl goes here -->
<Ellipse Fill="Red" Width="20" Height="20" ToolTip="{Binding ScreenPoint}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
您还需要确保DataObjects属性是ObservableCollection,然后才能添加和删除对象,并在UI中自动更新已更改的项目,帮助解决刷新性能问题。这些对象被放置在画布上,需要用户拖动。ItemsControl是否支持此类操作?我环顾了一下四周,不太确定(而且我还不是WPF专家)。谢谢,进一步研究一下。所以我认为虚拟化不会有什么帮助,因为所有的元素都是可见的,但我会对每个项目进行模板化,看看这是否有帮助。谢谢,+1,我会让你知道它是如何进行的。嗯,看起来我无法绑定这些控件的位置,所以我可能会回到我开始的地方。