Связывание коллекции объектов данных в модели с группой элементов управления в представлении (WPF) - PullRequest
3 голосов
/ 24 марта 2011

еще один вопрос от WPF от меня здесь.

В настоящее время у меня есть ситуация, в которой мне нужно связать ObservableCollection<T> объектов данных в модели с группой UserControls в представлении. Количество объектов данных часто меняется, и мне нужно создавать эти 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 );
    }
}        

Итак, как вы видите, я отвечаю (в коде) на измененное свойство и динамически создаю группу новых элементов UserControls. Этот код вызывается, когда соответствующий объект данных «Перемещен» (он содержит свойство Point), добавлен, создан или установлена ​​вся коллекция. Проблема в том, что это может занять (в худшем случае 100+ элементов) одну секунду или более, что недопустимо. Сами элементы управления просты; только сетка и форма (эллипс).

TLDR;


Итак, я полагаю, что спрашиваю, сталкивался ли кто-нибудь с подобной ситуацией. Динамическое создание элементов управления в ответ на изменение коллекции и добавление / удаление их из пользовательского интерфейса, аналогично тому, как свойство ItemsSource работает в ComboBox, ListBox, DataGrid и т. Д. Суть в том, что эти элементы управления должны учитывать перетаскивание мышью и область, расположенную в произвольных местах на холсте. Любая помощь приветствуется, спасибо заранее.

Ответы [ 2 ]

1 голос
/ 24 марта 2011

Почему бы вам не использовать виртуализированный ItemsControl с ItemTemplateSelector? Если элементы управления просты, можно использовать для них шаблоны данных, поэтому не нужно создавать пользовательские элементы управления. Поскольку элемент управления виртуализирован, будут отображаться только видимые элементы, поэтому он должен быть быстрее.

0 голосов
/ 24 марта 2011

Это именно то, для чего предназначен ItemsControl, но есть несколько складок с макетом, когда вам нужно использовать Canvas и вытягивать позиции из данных. Это не сложно, но для правильной работы нужно несколько разных частей. Вот быстрый пример, предполагая, что ваша 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, и тогда вы сможете добавлять и удалять объекты и получать автоматические обновления в пользовательском интерфейсе только тех элементов, которые изменились, что помогает повысить производительность обновления. проблема.

...