Setting ItemTemplate in code behind doesn't refresh display - silverlight

I have a ListBox which displays more or less data depending on the level of details that users choose. The ListBox has a dynamic ItemsSource set in XAML:
ItemsSource="{Binding Items}"
and its default ItemTemplate is set using
ItemTemplate="{StaticResource FewDetails}"
in code behind I use
MyListBox.ItemTemplate = this.Resources["LotsOfDetails"] as DataTemplate
but the list box doesn't refresh.
The only way I've found to make this work is to use a CollectionViewSource as my ItemsSource, and to manually refresh the view using View.Refresh().
Any ideas why the straightforward solution doesn't work?

Related

Which tool is the best option for doing search in Datagrid in wpf?

I have created search option using combobox, for example
In combobox1 items are m1,m2,m3,m4,m5 based on that, if m1 item selected then
another combobox2 displays with items a,b,c,d and if a item is selected another
combobox3 dispalys, based on last combobox it searches on the datagrid.
I think it is long process, use of many combobox makes it lenghty. Is any
other way is their to implement this. plz help
<ComboBox Grid.Column="1"
Grid.Row="1"
x:Name="cmbType"
VerticalAlignment="Top"
IsEnabled="{Binding IsOther}"
ItemsSource="{Binding Source={StaticResource enumTypeOfType}}"
SelectedItem="{Binding SearchType,Mode=TwoWay}"
SelectedIndex="{Binding CmdResIndex,Mode=TwoWay}"
IsSynchronizedWithCurrentItem="True"
SelectionChanged="DataSource1"
Margin="0,0,1,0">
</ComboBox>
So if i get this right, you have a collection a, which goes to collection b,etc, and the second collection will change based on the selected item of the first? You have to remember, that since the data will change for each selection, hard coding the value is out of the question.
Knowing this, WPF provides you with a great mechanism for this. Using a stackpanel, with a list view will actually work.
<ItemsControl ItemsSource="{binding collections}" ItemTemplate="{binding TemplateForListViewItems}" ItemPanelTemplate="{binding itemPanelTemplate}"></ItemsControl>
Now, with the items control, one can simply set an ItemTemplate/DataTemplate, to set the styling of each control. Linking to the onclick event, or using interactions, you can simply do collections.Add to add your new list view with generated data for the selection, and done.

How to make a TextBox update its source ListBox's SelectedValue (without code-behind?)

I'm learning WPF and am really trying to drill down on binding until I can do it like a boss. But I'm having a bit of an issue.
In xaml, I have a ListBox like so:
<ListBox Name="AccountsDisplay"
SelectedValuePath="Username"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Accounts}"
/>
And I have a TextBox that's pulling "Username" from said ListBox.
<TextBox Text="{Binding ElementName=AccountsDisplay, Path=SelectedValue}"/>
Note: Accounts is both an ObservableCollection and all objects added to it are of type Account, which is purely a data class that extends INotifyPropertyChanged, and has properties such as Username, Password, etc.
The TextBox is pulling the Username property properly, and updates any time I change selection in the ListBox (which is populated with pretty lil' Account info entries, as intended), but I cannot then click on the TextBox and attempt to update the Username portion of entries in the ListBox.
My gut tells me I'm going about this TextBox the wrong way, since I won't be able to make other TextBoxes and pull any additional Account properties (thanks to SelectedValuePath already having a value), but I'm too new to WPF & XAML to see where the error is in my ways!
Am I barking up the right tree, or is there a more appropriate way to get a TextBox to synchronize with (and edit) the data in another UI Element?
Consider binding to the property of the actual DataContext of the list item selected.
I do not use SelectedValue because I am not sure of it's purpose.
Because of my ignorance regarding the use of that particular property, I just rely on SelectedItem.
I can then specify the property name that I want to bind to relative to the DataContext of the selected list item.
<TextBox Text="{Binding ElementName=AccountsDisplay, Path=SelectedItem.Username}"/>

Multiple ListBoxes binding their SelectedItem to the same property in ViewModel - better way?

I have a WPF listview, and in one column the cell may contain one or more ListBoxes.
When I right-click a ListBox I'm building a context menu where each item has a DelegateCommand. Currently I'm setting the command parameter to a SelectedListBox property on the page viewmodel itself as my delegate command needs to know which ListBox has been right-clicked.
However this is leading to weird behaviour, which I'm assuming is because I'm binding multiple ListBoxes to the same page-level property (SelectedListBox).
The relevant XAML for the cell template for the listview is as follows:
<DataTemplate x:Key="MultipleListBoxCellTemplate">
<ListBox SelectedItem="{Binding Path=DataContext.SelectedListBox, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Page}}}" />
</DataTemplate>
Is there a better way to get which ListBox has been right-clicked to my viewmodel, or can anyone think of another approach? Much appreciated :)
When you are building the context menu, you know which list box was selected, yes? I would probably wrap that up in the ICommand you are binding the context item to. This way, each command knows exactly which ListBox it was created by and can get the selected item from there.
Alternately, you may be able to get around the issue with using SelectedItem by changing your binding to OneWayToSource so that the data only flows from the View back to the ViewModel. You may still have timing issues, which I suspect is your current problem, but depending on exactly what is going on, that may resolve it.

wpf combobox binding issue

when i bind one combobox with other combobox items... with the following code
<ComboBox ItemsSource="{Binding ElementName=cbo1, Path=Items}" Name="cbo2" />
it works fine but when i select something from cbo1 and come back to select something in cbo2.. it doesn't list anything nor cbo1 does...
what could be wrong?
The Items property is a CollectionView which wraps the ItemsSource, and includes things like the currently selected item, sort order, etc. If you set ItemsSource on an ItemsControl, your data is automatically wrapped in a CollectionView, and that's what gets set as the Items property. I suspect that this class isn't suitable for sharing between two controls.
If you're using ItemsSource to set the data on cbo1, you could maybe bind to ItemsSource instead? That is:
<ComboBox ItemsSource="{Binding ElementName=cbo1, Path=ItemsSource}" Name="cbo2" />
Haven't had chance to test this, but it's an educated guess :-)

WPF CheckBox IsChecked can't be reset when page(data source) is updated

I have question on the checkbox.
First of all,
I have a usercontrol which has a list box like this and this user control will be switched by 2 button and then the data source is changed and then the the displayed officer status will be changed:
When I check the checkbox, Officers[0].IsOnDuty will be changed to true.
The problem is:
When I click another button and switch to another data source, this checked check box is still checked but the Officers[0].IsOnDuty for this data source is false.
How to solve this?
The data context of the list box item is an item for your officers collection, not the collection itself. And using a one way binding is incorrect, as the data source (the officer) will not be updated. So change the DataTemplate to:
<CheckBox IsChecked="{Binding Path=IsOnDuty, Mode=TwoWay}" />
*Here is the list box xaml:
<ListBox ItemsSource="{Binding OfficersCollection}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=Officers[0].IsOnDuty, Mode=OneWay}" />
*
The problem with your approach is that once you change the ItemsSource (by switching to the next page) your chekcbox is still bound to the item of the first collection. I think this happens because you explicitly use an indexer for the binding Path=Officers[0].IsOnDuty
Your samplelist box xaml does not really make sense. the ItemsSoruce is a OfficerCollection and your ItemTemplate binds to a collection of Officers too. Depending on what you are trying to accomplish you should do one of the following:
If your are just interested in the first officer (as your sample suggest), add a DependencyProperty FirstOfficer (or a INotifyPropertyChanged) property to your collection and bind to it: IsChecked="{Binding Path=Officers.FirstOfficer, Mode=OneWay}"
If you however are interested in all Officers and want checkboxes for all of them you should create a DataTemplate for the Officer type and use this as the ItemTemplate.
Generally you can stay out of a lot of trouble if you stick with MVVM and really tailor your ViewModel objects very close to what the View needs so you can bind your View to the ViewModel in the simplest possible way. Think of the ViewModel as the View you want to build but without a visual representation.

Resources