简体   繁体   English

WPF数据绑定非常慢

[英]WPF databinding very slow

I had a question some time ago (this is NO duplicate) as you can see here: WPF Simple DataMatrix . 不久前我有一个问题(没有重复),您可以在这里看到: WPF Simple DataMatrix I asked about creating a matrix of LED lights on screen. 我问有关在屏幕上创建LED灯矩阵的问题。 I used to that the marked answer and created the matrix. 我习惯了标记答案并创建了矩阵。 It is displayed very well and I also applied commands on the Ellipse so I can edit the Matrix but also that works without any lag. 它显示得非常好,并且我还在椭圆上应用了命令,因此我可以编辑矩阵,但也可以毫无滞后地工作。

As result this is my code for the Matrix: 结果,这是我的矩阵代码:

<ItemsControl x:Class="HTLED.WPF.Controls.LedGrid"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:Data="clr-namespace:HTLED.Data;assembly=HTLED.Data"
         xmlns:Controls="clr-namespace:HTLED.WPF.Controls"
         xmlns:Commands="clr-namespace:HTLED.Client.Commands;assembly=HTLED.Client"
         xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         xmlns:ViewModel="clr-namespace:HTLED.Client.ViewModel;assembly=HTLED.Client"
         mc:Ignorable="d"
         d:DataContext="{d:DesignInstance ViewModel:LedContainerViewModel}" Name="ledGridRoot" >
<ItemsControl.Resources>
    <DataTemplate x:Key="ledTemplate" DataType="{x:Type Data:Led}">
        <Ellipse Name="ellipse" Fill="Green" Stretch="Uniform" SnapsToDevicePixels="True">
            <Interactivity:Interaction.Triggers>
                <Interactivity:EventTrigger EventName="PreviewMouseMove">
                    <Commands:CommandTrigger Command="{Binding ElementName=ledGridRoot, Path=DataContext.LedGridViewModel.LedMouseMoveCommand}" PassEventArgsToCommand="True"/>
                </Interactivity:EventTrigger>
                <Interactivity:EventTrigger EventName="PreviewMouseLeftButtonDown">
                    <Commands:CommandTrigger Command="{Binding ElementName=ledGridRoot, Path=DataContext.LedGridViewModel.LedOnCommand}" PassEventArgsToCommand="True"/>
                </Interactivity:EventTrigger>
                <Interactivity:EventTrigger EventName="PreviewMouseRightButtonDown">
                    <Commands:CommandTrigger Command="{Binding ElementName=ledGridRoot, Path=DataContext.LedGridViewModel.LedOffCommand}" PassEventArgsToCommand="True"/>
                </Interactivity:EventTrigger>
            </Interactivity:Interaction.Triggers>
        </Ellipse>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=State}" Value="Off">
                <Setter TargetName="ellipse" Property="Fill" Value="Red"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <ItemsControl ItemsSource="{Binding}" ItemTemplate="{StaticResource ledTemplate}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Controls:StretchStackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

In the background I have a class called LedMatrix. 在后台,我有一个名为LedMatrix的类。 It has a property with the collection of the leds: 它具有收集led的属性:

    ObservableCollection<ObservableCollection<Led>> _leds;
    public ObservableCollection<ObservableCollection<Led>> Leds
    {
        get { return _leds ?? (_leds = CreateMatrix(XSize, YSize)); }
        set { SetProperty(value, ref _leds, () => Leds); }
    }

The matrix is contained by another control: 该矩阵包含在另一个控件中:

<Canvas x:Class="HTLED.WPF.Controls.LedContainer"
         ....
         mc:Ignorable="d" 
         d:DataContext="{d:DesignInstance ViewModel:LedContainerViewModel}"
         d:DesignHeight="300" d:DesignWidth="300" Name="layoutRoot" Drawing:DrawingCore.EnableDrawing="True">
<Viewbox Canvas.Top="0" Canvas.Left="0" Width="{Binding ElementName=layoutRoot, Path=ActualWidth}"
         Height="{Binding ElementName=layoutRoot, Path=ActualHeight}">
    <Grid>
        <Controls:LedGrid Width="50000" Height="25000" Margin="500" DataContext="{Binding Path=Main.LedContainerViewModel}" ItemsSource="{Binding Path=LedContentContainer.Content}" />
    </Grid>
</Viewbox>

As you can see I set the ItemsSource of the Matrix in the container. 如您所见,我在容器中设置了矩阵的ItemsSource。 That Itemssource Is a Interface like this: ItemsSource是这样的接口:

public interface ILedContentContainer
{
    LedMatrix Content { get; set; }
}

And the LedMatrix I already showed before (the ObservableCollection<ObservableCollection<Led>> ). 我之前已经展示过的LedMatrix( ObservableCollection<ObservableCollection<Led>> )。

And now the very important: I have the change the LedMatrix (the Itemssource of LedGrid - see LedGridContainer) very often because it is some kind of an animation. 现在非常重要:我经常更改LedMatrix(LedGrid的Itemssource-请参见LedGridContainer),因为它是某种动画。 The problem is that that all is very very slow. 问题在于,一切都非常缓慢。 So I wanted to ask if you know some optimations? 所以我想问一下您是否知道一些优化?

Again I have to change the LedMatrix very very fast. 同样,我必须非常非常快速地更改LedMatrix。

If you apply a whole new ObservableCollection each time as Led changes, the complete grid has to be rendered again and again. 如果在Led更改时每次应用一个全新的ObservableCollection ,则必须一次又一次渲染整个网格。 You should change the State property of the Led's that are changing (they should fire PropertyChanged ). 您应该更改正在更改的Led的State属性(它们应触发PropertyChanged )。

Also, if the amount of Led's is constant, you don't need an ObservableCollection at all. 另外,如果Led的数量恒定,则根本不需要ObservableCollection You can use any IEnumerable . 您可以使用任何IEnumerable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM