Sorry for noob question. Perhaps this is not a question - but I need a tutorial sample/ I am trying to write a model task to get "handy" with mvvm pattern in wpf. I am decide to write something like librarian helper. That is one simple wpf window with one combobox(for selecting if the book is fantasy or sf), textbox (for book name input), button Add, and a treeview with a tree like:
Books
------>ScienceFic
----->bookName1
----->bookName2
------->Fantasy
------>bookName3
And I have some difficulties with binding and separation view model from view. Could You help me?
public enum LibraryType
{
ScienceFic,
Fantasy
}
Class Model: INotifyPropertyChanged
{
private int bookId;
private string bookName;
private LibraryType bookType;
public event PropertyChangedEventHandler PropertyChanged;
//....and for all this fields I have used a INotifyPropertyChanged as
/*
http://stackoverflow.com/questions/1315621/implementing-inotifypropertychanged-does-a-better-way-exist
*/
}
At this point the MODEL is finished I think.
Now about VIEW: I have simply open editor of MainWindow and manually added button, textbox, combobox, and a treeview. After addition of
comboBox1.ItemsSource = Enum.GetValues(typeof(LibraryType)).Cast<LibraryType>();
comboBox1.SelectedIndex = 0;
I have initialized my combo with right types of books))) But((, I have done this in code, not in XAML - is this right for MVVM Binding? (first question) Next, I have bind (as I suppose) my textBox text to current book name property in ViewModel (I have done this in XAML like this):
<TextBox Text="{Binding Path=CurrentBookName}"/>
is this right? (second question)
And, finally, VIEWMODEL
Class ViewModel
{
private string currentBookName;
private LibraryType selectedBookType;
public event PropertyChangedEventHandler PropertyChanged;
//also properties and OnPropertyChanged/SetField functions like in Model class
//and finally I have created two lists for book storing
private List<Model> sfStorage = new List<Model>();
private List<Model> fantasyStorage = new List<Model>();
//and simple getters for this two lists, like:
public List<Model> GetSFStorage
{
get{return this.sfStorage;}
}
//and a simple function for addition of new books
//that I plan to call when AddButton pressed
public void Addition(???)
{
if (!string.IsNullOrEmpty(currentBookName))
{
//? I have add CurrentBookName in XAML of View (see above)
//?but is it enough to have a property of CurrentBookType
//to grant that a valide value from combobox will be here?
var modelNewBook = new Model(CurrentBookName,CurrentBookType);
switch (selectedBookType)
{
case LibraryType.ScienceFic:
sfStorage.Add(modelNewBook);
break;
case LibraryType.Fantasy:
fantasyStorage.Add(modelNewBook);
break;
default:
return;
}
}
}
Now I am only few step out of success (may be) BUT, how I could connect a treeView with this two lists in xaml or in code And how could I call Addition function when an Addbutton pressed (third and main question)? Perhaps, this is noob question, but I really need an sample. And, (perhaps) this question will be helpfull for others who try to understand MVVM and binding.
The following code is a quick hack of your application. I also understood that you have problems with the treeview so i only display the code passanges to the treeview and i fill my books list inside the constructor of my view model to have some data
Model:
internal class Book : NotifyPropertyChangedBase
{
private string name;
private BookType type;
public BookType Type
{
get => this.type;
}
set
{
this.SetProperty( ref this.type,value );
}
}
public string Name
{
get => return this.name;
set
{
this.SetProperty( ref this.name,value );
}
}
ViewModel:
private readonly List<Book> books;
public MainViewModel( )
{
this.books = new List<Book>
{
new Book
{
Name = "Book 1",
Type = BookType.Fantasy
},
new Book
{
Name = "Book 2",
Type = BookType.Fantasy
},
new Book
{
Name = "Book 3",
Type = BookType.Fantasy
},
new Book
{
Name = "Book 4",
Type = BookType.SciFi
}
};
}
public ICollectionView Books
{
get
{
var source = CollectionViewSource.GetDefaultView( this.books );
source.GroupDescriptions.Add( new PropertyGroupDescription( "Type" )
);
return source;
}
View:
<TreeView ItemsSource="{Binding Books.Groups}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
From what I understand you need help generating the hierarchy in TreeView
using a ViewModel
. Todo this you will be using a HierarchicalDataTemplate
. Your ViewModel
will require a collection of children, and you will use the simply bind the ItemsSource
property of the HierarchicalDataTemplate
to that collection.
Take a look at this simple example someone made: TreeView and HierarchicalDataTemplate, Step-by-Step
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With