2012-08-16 4 views
1

У меня возник вопрос некоторое время назад (это не дубликат), как вы можете видеть здесь: 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.

ответ

0

Если вы применяете целое новое ObservableCollection каждый раз, когда Led изменяется, вся сетка должна быть визуализирована снова и снова. Вы должны изменить свойство Led's State, которое меняется (они должны стрелять PropertyChanged).

Кроме того, если количество Led's постоянное, вам не нужен только ObservableCollection. Вы можете использовать любые IEnumerable.

+0

Хорошо, я просто узнал, что мне просто нужно синхронизировать состояние, и производительность становится огромной. Но вещь с ObservableCollection ... Количество светодиодов ist constant, поэтому я не должен использовать один ... вы правы, но имеет ли наблюдаемый коллектив производительность? –

+0

Да, вам это не нужно. Преимущество ObservableColletion заключается в том, что элемент удаляется, добавляется или перемещается по порядку, связанный ItemControl снова отображает измененные элементы. Но в вашем случае изменяется только свойство элемента внутри коллекции, поэтому эта функция не используется. Это может стоить производительности при заполнении коллекции, позже я не думаю. – DanielB