У меня возник вопрос некоторое время назад (это не дубликат), как вы можете видеть здесь: WPF Simple DataMatrix. Я спросил о создании матрицы светодиодных индикаторов на экране. Я использовал для этого отмеченный ответ и создал матрицу. Он отображается очень хорошо, и я также применял команды на Эллипсе, поэтому я могу редактировать Матрицу, но и это работает без какого-либо отставания.WPF databinding очень медленно
В результате это мой код Матрицы:
<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>
На заднем плане у меня есть класс с именем LedMatrix. Он имеет свойство с коллекцией светодиодов:
ObservableCollection<ObservableCollection<Led>> _leds;
public ObservableCollection<ObservableCollection<Led>> Leds
{
get { return _leds ?? (_leds = CreateMatrix(XSize, YSize)); }
set { SetProperty(value, ref _leds,() => Leds); }
}
Матрица содержатся другим управление:
<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>
Как вы можете видеть, что я установить ItemsSource Матрицы в контейнер. Это ItemsSource представляет собой интерфейс, как это:
public interface ILedContentContainer
{
LedMatrix Content { get; set; }
}
И LedMatrix я уже показал ранее (ObservableCollection<ObservableCollection<Led>>
).
И сейчас очень важно: У меня есть изменить LedMatrix (в ItemsSource из LedGrid - см LedGridContainer) очень часто, потому что это своего рода анимации. Проблема в том, что все очень медленно. Поэтому я хотел спросить, знаете ли вы какие-то оптимизации?
Снова я должен очень быстро изменить LedMatrix.
Хорошо, я просто узнал, что мне просто нужно синхронизировать состояние, и производительность становится огромной. Но вещь с ObservableCollection ... Количество светодиодов ist constant, поэтому я не должен использовать один ... вы правы, но имеет ли наблюдаемый коллектив производительность? –
Да, вам это не нужно. Преимущество ObservableColletion заключается в том, что элемент удаляется, добавляется или перемещается по порядку, связанный ItemControl снова отображает измененные элементы. Но в вашем случае изменяется только свойство элемента внутри коллекции, поэтому эта функция не используется. Это может стоить производительности при заполнении коллекции, позже я не думаю. – DanielB