Я пытаюсь выбрать лучший способ реализовать этот интерфейс в манере MVVM.Я новичок в WPF (например, 2 месяца), но у меня огромный опыт работы с WinForms.![enter image description here](https://i.stack.imgur.com/CrZtD.png)
ListBox здесь действует как TabControl (поэтому он переключает представление вправо) и содержит в основном тип элемента, отображаемый в таблицах.Весь пользовательский интерфейс является динамическим (элементы ListBox, TabItems и Columns определяются во время выполнения).Приложение предназначено для WPF и Silverlight.
Классы, которые нам нужны для ViewModel:
public abstract class ViewModel : INotifyPropertyChanged {}
public abstract class ContainerViewModel : ViewModel
{
public IList<ViewModel> Workspaces {get;set;}
public ViewModel ActiveWorkspace {get;set;}
}
public class ListViewModel<TItem> where TItem : class
{
public IList<TItem> ItemList { get; set; }
public TItem ActiveItem { get; set; }
public IList<TItem> SelectedItems { get; set; }
}
public class TableViewModel<TItem> : ListViewModel<TItem> where TItem : class
{
public Ilist<ColumnDescription> ColumnList { get; set; }
}
Теперь вопрос заключается в том, как подключить это к View.
Есть два базовых подхода, которые я вижу здесь:
- С XAML: из-за отсутствия поддержки Generics в XAML я потеряю строгую типизацию.
- Без XAML: я могуповторное использование того же
ListView<T> : UserControl.
Далее, как связать данные, я вижу 3 метода здесь (с XAML или без здесь не имеет значения).Поскольку не существует простой DataBinding для столбцов DataGrid или TabItems TabControl, методы, которые я вижу, являются:
- Использовать DataBinding с IValueConverter: я думаю, что это не будет работать с WPF | Silverlight из встроенных элементов управления, так какнекоторые свойства, которые мне нужны, доступны только для чтения или не могут быть привязаны в дуплексном режиме.(Я не уверен в этом, но я чувствую, что это не будет работать).
Используйте ручную логику, подписавшись на INotifyPropertyChanged в View: ViewModel.PropertyChanged + = .... ViewModel.ColumnList.CollectionChanged + = ....
Используйте пользовательские контроллеры, поддерживающие эту привязку: используйте код самостоятельно или найдите сторонние элементы управления, поддерживающие эту привязку (мне не нравится этот параметр, мой навык WPFслишком низок, чтобы кодировать это сам, и я сомневаюсь, что найду бесплатные элементы управления)
Обновление: 28.02.2011 Все становится все хуже и хуже, ярешил использовать TreeView вместо ListBox, и это был кошмар.Как вы, наверное, догадались, TreeView.SelectedItems является свойством только для чтения, поэтому для него нет привязки данных.Хм, хорошо, давайте сделаем это по-старому и подпишемся на события, чтобы синхронизировать представление с viewmodel.В этот момент неожиданно обнаружилось, что DisplayMemberPath ничего не делает для TreeView (ммм, хорошо, давайте сделаем его старым способом ToString ()).Затем в методе View я пытаюсь синхронизировать ViewModel.SelectedItem с TreeView:
private void UpdateTreeViewSelectedItem()
{
//uiCategorySelector.SelectedItem = ReadOnly....
//((TreeViewItem) uiCategorySelector.Items[uiCategorySelector.Items.IndexOf(Model.ActiveCategory)]).IsSelected = true;
// Will not work Items's are not TreeViewItem but Category object......
//((TreeViewItem) uiCategorySelector.ItemContainerGenerator.ContainerFromItem(Model.ActiveCategory)).IsSelected = true;
//Doesn't work too.... NULL // Changind DataContext=Model and Model = new MainViewModel line order doesn't matter.
//Allright.. figure this out later...
}
И ни один из методов, которые я мог придумать, не сработал ....
А вот ссылка намой пример проекта, демонстрирующий Ад библиотеки управления с MVVM: http://cid -b73623db14413608.office.live.com / self.aspx / .Public / MVVMDemo.zip