ListView default selected items mvvm - c#

I have ListView with dependency property for selecting more than one item. ListView sample code is here:
<ListView ItemsSource="{Binding Test}"
ItemTemplate="{StaticResource SomeTemplate}"
SelectionMode="Multiple"
multipleBind:SelectionChangedCommand.Command="{Binding SelectionChangedCommand}">
</ListView>
It works properly but what I want is pre-select default items and I don't know How do it. Is it a possible? Please give me some hit.
Thanks

Related

Problem with multiple ListBox binding same SelectedItem property

I have a screen in WPF that needs to list data from same database table, but separately by status. In the print each column is a different status and each is a ListBox, the SelectedItem binding for all ListBox is the same property in ViewModel. The problem is when an item is selected in some ListBox it still selected even after I select an item from other ListBox and when the focus return to the first ListBox (with Tab key for example) the item gets the selected style. Any idea how to resolve this? I can change the ListBoxes for other solution too, at this moment i can't see other solution.
Sorry for my bad English, and I don't know if the explanation is much clear this feature is a bit complicated to explain, but any doubts I'll provide the answers.
Thanks for all.
do you want to have the same item selected in each listbox? Try adding IsSynchronizedWithCurrentItem="true" to every listbox in xaml:
<StackPanel>
<!--both comboboxes are synchronized with each other-->
<ComboBox ItemsSource="{Binding Products}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name"/>
<ComboBox ItemsSource="{Binding Products}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name"/>
</StackPanel>

combobox and listview binding issue wpf c#

I have a combobox which displays listview on dropdown, I am following MVVM Pattern and i have also set the public property in my Viewmodel and it works fine when i am assigning it to the Label but for Combobox it doesn't seem to rely on my binding. i tried numerous ways but unable to find the issue.
XAML :
<ComboBox Name="SearchBox" IsEditable="True" Background="White" md:HintAssist.Hint="Search MUID" Grid.Column="1" Margin="5 0 0 0"
Grid.Row="0" Height="40" Width="400" HorizontalContentAlignment="Left" HorizontalAlignment="Left" SelectedItem="{Binding ElementName=lstview ,Path=SelectedItem}" >
<ComboBoxItem>
<ListView x:Name="lstview" ItemsSource="{Binding filterSW}"
SelectedItem="{Binding SelectedMU}"
Height="200" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.View>
<GridView>
<GridViewColumn Width="130" Header="Mu-ID" />
<GridViewColumn Width="130" Header="MU-Identifier" DisplayMemberBinding="{Binding MU_Identifier}" />
<GridViewColumn Width="130" Header="Status" DisplayMemberBinding="{Binding RequestType}" />
<GridViewColumn Width="130" Header="UniqueID" />
</GridView>
</ListView.View>
</ListView>
</ComboBoxItem>
</ComboBox>
This works fine for me when i am using the public property and accessing its element , i also tried setting text={Binding SelectedMU.MU_Identifier} and selectedvalue but its just not working.
<Label Grid.Column="3" HorizontalAlignment="Center" Background="GreenYellow" Content="{Binding SelectedMU.MU_Identifier}"></Label>
It looks like you're trying to show a multi-column list in your ComboBox dropdown instead of the standard list where each item shows just a text line.
To achieve this effect you've placed a ListView inside the dropdown.
Unfortunately, this is just not going to work.
Both ComboBox and ListView descend from Selector which is an abstraction that allows to select an item from a list. This limits the property SelectedItem to one of the items that are contained in the list. If you try to assign to this property any value that it not in the list, the assignment is not going to work and the property will retain the value it had before you did the assignment.
Now, the list could either be specified right inside XAML or provided as a binding to property ItemsSource. You do the binding correctly for the ListView. But for the ComboBox you don't specify that binding. Instead you specify exactly one item of type ComboBoxItem which contains the whole ListBox as its value. So the only value that could be successfully assigned to the SelectedItem property of the ComboBox is that single ComboBoxItem. But your binding is never going to assign that value, that's why the ComboBox never shows anything when closed.
When it's open it does show the single item which contain the ListView but this is just an optical effect. The data binging is not going to work. The reason why it works for the Label is because the Label is not constrained and can show anything that the ListView tells it to show.
You can synchronize the ListView and the ComboBox only when both controls have the same bindings for both ItemsSource and SelectedItem properties. But in this case you won't be able to place the ListView inside the dropdown.
The closest you can get to what you want is by customizing the ComboBox's template as described in https://zamjad.wordpress.com/2012/08/15/multi-columns-combo-box, for example. What this won't give you compared to ListView is the column headers. Also, the columns will be evenly spaced inside the dropdown but this is what you have in your ListView anyway.
If you want to auto-size them, you'd need to add Width="Auto" SharedSizeGroup="cN" to each ColumnDefinition where "cN" should have the column number instead of N to make them unique within the Grid and add Grid.IsSharedSizeScope="True" to the <ComboBox >
That's a lot of trouble for something that one would expect to be much simpler, but, unfortunately, you cannot place a ListView inside the ComboBox's template, that's a limitation of how the base class Selector works with its items list.
There are other options if you are open to consider 3rd party control libraries. I worked with Syncfusion, they have SfMultiColumnDropDown which does what you want. I'm pretty sure other popular libraries have similar controls as well.

Binding SelectedItem of ListView inside of DataTemplate

I'm currently working on a music player app and I'm getting stuck on keeping the playing track highlighted in all ListViews in the app.
For example, there is a page with a list of albums, each of which contains a DataTemplate with a list of songs. All is well and good when you first select it and the selected item is bound to the viewmodel. But on navigating away from and the returning to that page, the viewmodel retains the information about which sing was playing, but the binding doesn't cause the item to be highlighted.
Here is my XAML:
<ListView x:Name="lstSongs"
ItemsSource="{Binding attachments}"
SelectionChanged="lstSongs_SelectionChanged"
ScrollViewer.VerticalScrollMode="Disabled"
SelectedValue="{Binding DataContext.selectedSong, ElementName=Group_Page}"
SelectedItem="{Binding DataContext.selectedSong, ElementName=Group_Page}"
ItemContainerStyle="{StaticResource ListViewTextHighlight}"
Grid.Row="1">
Binding the SelectedItem and SelectedValue was just to see if either one would work.
I'm probably missing something obvious, but nevertheless I hope someone can help me out.
Thanks!
I think the SelectedItem binding needs to be Mode=TwoWay
SelectedItem="{Binding DataContext.selectedSong, ElementName=Group_Page, Mode=TwoWay }"

Adding custom control to listbox

I have a custom control ListItem. I need to display five such items in a window and these items could change during runtime; items could be added or deleted, or content could change in ListItem.
ListBox appears to be a good solution to display items. But what I have seen is we can add items and style them, and can handle updates with data trigger.
myListBox.Items.Add(new { FileName = "SomeFile", State="Uploaded" });
But we can not do something like
ListItem curItem = new ListItem();
myListBox.Items.Add(new { curItem });
Even if I do it shows empty item in the list.
So if I want to add my custom control to some listbox, how could that be possible. That is using ListBox just as a container so we can get away from the pain of positioning and all that after list changes. Or is there a better way to do that?
You are in luck - this is the bread and butter of WPF! Set the ItemsSource of your ListBox (possible in XAML or cs):
myListBox.ItemsSource = myEnumerableCollection;
or
<ListBox ItemsSource="{Binding MyItemsProperty}">
Use a DataTemplate (you do not need a UserControl) to style each item in XAML:
<ListBox ItemsSource="{Binding MyItemsProperty}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding FileName}"/>
<TextBlock Text="{Binding State}"/>
<!--Whatever you want-->
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If your collection is an ObservableCollection<T> changes to that collection (e.g. items added or removed) will be reflected in the ListBox automatically. If T implements INotifyPropertyChanged changes to properties on each item will also automatically show up on the UI.
For more see the WPF Binding Overview.
Don't create or manipulate UI elements in procedural code in WPF.
<ListBox ItemsSource="{Binding SomeCollection}">
<ListBox.ItemTemplate>
<DataTemplate>
<my:MyControl/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
where my:MyControl is a UserControl with whatever UI you want.

MVVM solution for wpf

Here's the situtation:
Data Context of the window is: MainViewModel.
It's built from ObservableCollections of SubViewModel.
Each SubViewModel has its own ObservableCollection of type String.
Now, I have a treeview. The ItemsSource is the ObservableCollection of the MainViewModel.(Means it is the SubViewModel collection).
I want that if an item is selected, then there will be displayed the ObservableCollection(type String) of the selected Item in the treeview.
How can I do that?
Some code:
<TreeView ItemTemplate="{DynamicResource TreeViewDataTemplate}" ItemsSource="{Binding SubViewModelCollection}"/>
I want to display the collection in a stack panel because of some reasons.
So: (TypeCollection is the string ObservableCollection of the item, it is currently not working of course)
<ItemsControl ItemsSource="{Binding TypeCollection}" x:Name="UserList" ItemTemplate="{StaticResource TemplateDataTemplate}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" HorizontalAlignment="Left" Grid.Column="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
I've been struggling alot with that, how can I achieve my target?
Bind the treeview ItemsSource to the UserList's SelectedItem.
<TreeView ItemTemplate="{DynamicResource TreeViewDataTemplate}"
ItemsSource="{Binding ElementName=UserList Path=SelectedItem.SubViewModelCollection}"/>
Assuming the items in UserList are type SubViewModel which has an IEnumerable<T> property called SubViewModelCollection.
I would recommend taking a look at Prism, particularly the portion pertaining to Event Aggregation. What this will allow you to do is publish an event in your application when an item in the TreeView is selected, consume that event elsewhere in your application and bind the ItemControl to the selected SubViewModel all without having to introduce any unnecessary coupling between these two pieces of your application.

Categories

Resources