Как установить привязку itemscontrol к другой ViewModel?

#c# #wpf #mvvm #datacontext #itemscontrol

#c# #wpf #mvvm #datacontext #itemscontrol

Вопрос:

Я пытался привязать список к своему ItemsControl и постоянно сталкивался с проблемами привязки, поэтому я пришел за помощью.

Мой код до сих пор:

 ...
<ssm:RecentFilesViewModel x:Key="RecentFilesVM" />
...

<ItemsControl ItemsSource="{Binding Source={StaticResource RecentFilesVM}, Path=Files} Margin="0 4 0 0">
    <ItemsControl.Template>
        <DataTemplate>
            <telerik:RadRibbonButton Width="285">
                <TextBlock Margin="0 0 0 2" Text="{Binding Path}" />
            </telerik:RadRibbonButton>
        </DataTemplate>
    </ItemsControl.Template>
</ItemsControl>
 

Я могу отобразить список, если я установлю datacontext для всего окна, НО это означает, что все мои другие привязки не работают. Это единственный объект, для которого требуется эта viewmodel, поэтому я хочу установить его уникальным для этого ItemsControl. Может кто-нибудь, пожалуйста, помочь мне заставить это работать? Это медленно сводит меня с ума.

Редактировать:

В настоящее время у меня это так, потому что для других объектов нет модели прямого просмотра. Мы пытаемся сохранить это как можно более разделенным, чтобы не было окна datacontext. Все остальное работает просто отлично. Я использую PRISM и Telerik.

При добавлении источника привязки все мои привязки команд (которые подключаются к другому классу в другом проекте) больше не работают. Есть ли способ убедиться, что мой источник привязки привязан к объекту, которым я манипулирую?

Комментарии:

1. Почему вам нужно сохранить разделенную ViewModel с View?

2. Наша цель — сделать программное обеспечение как можно более разделенным. Мы создаем много похожих приложений, поэтому хотим иметь возможность легко использовать код в нескольких местах без особых переделок. Сохраняя его разделенным, мы можем легко сказать: «Эй, это наша стандартная оболочка» и скопировать проект, чтобы затем просто подключить его к другим компонентам в других программных проектах.

3. Но когда вы отделяете ViewModel от View, не теряете ли вы характеристики или преимущества модели MVVM? Если вы хотите разделить эти части, вы бы ввели shell в представление?

4. Это то, что я на самом деле не объяснил. У нас есть наше основное представление (мы называем его app), а затем у нас есть это представление, которое называется оболочкой. Затем оболочка вводится в основное представление. В оболочке нет функциональности. Все, что является функциональным, связано с чем-то другим: например. команды находятся в другом проекте, которые связаны с использованием расширений разметки (x:Static commands:appcomands.savecommand ).

5. Я начинаю лучше понимать вашу модель программирования, поскольку в этот момент я впервые слышу эту модель. Если все понятно, вам нужно создать список в xmal и в этом представлении (или xmal) вам нужно связать этот список со StaticResource, это не так?

Ответ №1:

Добавьте свойство для RecentFilesViewModel внутренней ViewModel части окна DataContext .

Затем вы можете просто сделать:

 <ItemsControl ItemsSource="{Binding RecentFilesViewModel.Files}" Margin="0 4 0 0">
    <ItemsControl.Template>
        <DataTemplate>
            <telerik:RadRibbonButton Width="285">
                <TextBlock Margin="0 0 0 2" Text="{Binding Path}" />
            </telerik:RadRibbonButton>
        </DataTemplate>
    </ItemsControl.Template>
</ItemsControl>
 

Редактировать:

Основываясь на вашем недавнем редактировании, вы можете попробовать обернуть ItemsControl в сетку и установить для его DataContext значение RecentFiles . Обратите внимание, вам не нужно создавать ресурс / ключ для RecentFiled, вы можете просто получить к нему доступ, пока определено пространство имен.

 <Grid>
    <Grid.DataContext>
        <ssm:RecentFilesViewModel/>
    </Grid.DataContext>
    <ItemsControl ItemsSource="{Binding Files} Margin="0 4 0 0">
        <ItemsControl.Template>
            <DataTemplate>
                <telerik:RadRibbonButton Width="285">
                    <TextBlock Margin="0 0 0 2" Text="{Binding Path}" />
                </telerik:RadRibbonButton>
            </DataTemplate>
        </ItemsControl.Template>
    </ItemsControl>
</Grid>
 

Комментарии:

1. Для окна нет прямой viewmodel, у него нет datacontext . Все остальные элементы в окне ссылаются на использование расширений разметки, таких как x:Static. Мы пытаемся максимально отделить главное окно от всего, чтобы его было легче развернуть позже. Я пробовал {Привязка ssm:RecentFilesViewModel . Files} но это тоже не работает. (ssm обозначает пространство имен, в котором находится класс RecentFilesViewModel)

2. Весь смысл модели представления заключается в предоставлении данных для представления. Как только вы установите datacontext элемента управления ItemsControl к модели представления, вы связали модель представления. Вы могли бы также связать его в окне и использовать модель представления так, как она предназначена для использования. Если вы действительно хотите развязки, вам следует взглянуть на Prism и Unity. Вы можете потенциально усложнить обслуживание вашего приложения в долгосрочной перспективе, пытаясь обойти связь с моделями просмотра, а не просто использовать их так, как они предназначены для использования.

3. Это имеет смысл, но мы стараемся этого не делать. Я не упоминал, что мы используем PRISM и telerik совместно. Я обновил свой приведенный выше код до того, с чем мне удалось поработать до сих пор, но у меня все еще возникают проблемы.