ListBox bound to collection does not automatically refresh. Why? - wpf

I have a ListBox which is bound to a collection. When I add an item to the collection I see no change in the ListBox.
However, when I resize the window a little, then the new item suddenly appears in the ListBox. So the binding seems to be working, just the refresh is missing.
What might I be doing wrong here?
XAML:
<ListBox Grid.Row="2" Grid.Column="1" Name="TestModules" ItemsSource="{Binding ModuleList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding TE}"/>
<TextBlock Text="-"/>
<TextBlock Text="{Binding AF}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code:
private List<PruefModule> _moduleList = new List<PruefModule>();
public ICollectionView ModuleList { get; private set; }
ModuleList = CollectionViewSource.GetDefaultView(_moduleList);
_moduleList.Add((PruefModule)ModulesGrid.SelectedItem);

You should use an ObservableCollection instead of the ICollectionView and it should work ok.
From MSDN:
Represents a dynamic data collection that provides notifications when
items get added, removed, or when the whole list is refreshed.

like Adrian said you should use ObservableCollection.
nevertheless you can call Refresh after adding a item.
_moduleList.Add((PruefModule)ModulesGrid.SelectedItem);
ModuleList.Refresh();

Related

WPF: DataTemplate not applied to dynamically added ListBoxItems

I'm creating a UserControl that contains a Listbox. I want the User to be able to add new Listbox Items through a ButtonClick. Adding the new Items works fine but it seems that my DataTemplate is not applied to the newly added Item.
This is how I assign my DataTemplate:
<ListBox x:Name="UserControlListBox" ItemsSource="{Binding Path=ItemsSource, ElementName=MyCustomListControl}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding}"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}" HorizontalAlignment="Left"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This is how I add a new ListboxItem:
public void AddItem(object listBoxItem)
{
IEnumerable enumerable = ItemsSource;
List<object> asList = enumerable.Cast<object>().ToList();
asList.Add(listBoxItem);
ItemsSource = asList;
}
I need a TextBox around my ListItem-Content in order to use the TextTrimming-Property. It works fine for the Items that are already inside the List that is assigned to the ItemSource Property of my UserControl but not to the ones that are added through the ButtonClick as you can see
here

WPF binding UserControl collection to ItemsControl. DataTemplate issue

http://www.filedropper.com/wpfapplication9
that link has a project in VS2013 with a sample issue.
my problem is, how to set DataTemplate to UserControl, in ItemsControl.
<ItemsControl ItemsSource="{Binding Collection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
my Collections is a
public IEnumerable<MyUC> Collection {get;}
my MyUC is a
public partial class MyUC : UserControl
{
public string Title { get; set; }
}
When i try to show that collection im getting
MyUC.Content
insted
MyUC.Title
when i change ItemsSouce to ListBox, datatemplate starts working.
but i need to show collection without ListBox addons.
If I understand you correctly, you just want to display the Title property value of your UserControls from your collection. All that you have to do is to declare an appropriate DataTemplate for them in the Resources section:
<DataTemplate DataType="x:Type={YourPrefix:MyUC}">
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
To be honest though, you seem to be going about this in the wrong way. In WPF, we generally don't put UI elements into collections, instead preferring to work with custom data classes that have DataTempates to define what they should look like. In your case, it would look something like this:
<DataTemplate x:Key="TitleTemplate" DataType="x:Type={YourPrefix:MyDataClass}">
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
<DataTemplate x:Key="ControlTemplate" DataType="x:Type={YourPrefix:MyDataClass}">
<YourControlPrefix:MyUC />
</DataTemplate>
You'd then use the TitleTemplate when you want to see just the Title property values and the ControlTemplate when you want to see the whole UserControl.

Xaml - combo box - why does selectedValue NOT work with multiple columns?

Hi and thanks for your help.
The following xaml works just fine:
<ComboBox Name="cboCit_type"
IsSynchronizedWithCurrentItem="True"
mvvm:View.FlowsWithPrevious="True"
ItemsSource="{Binding Path=cuCodeInfo.CitTypes}"
SelectedValuePath="code"
DisplayMemberPath="code"
Text="{Binding cit_type}"
IsEditable="true"
IsReadOnly="false"
SelectedValue="{Binding Path=cit_type}">
</ComboBox>
cuCodeInfo.CitTypes is simply a list of items that are available. There are a number of public properties, but the 2 in question are "code" and "description".
Right now, I show the available code values and the user selects one. If one was already selected, then it shows when the page is displayed. This is all good.
So then I thought it might be nice to show both the code and the description. I figured it shouldn't be too hard...
So I removed the DisplayMemberPath statement and added in an ItemTemplate.
When I did so everything looked great until I tried to select an item from the list. When I did so, instead of showing the selected code, I would get an empty string. I have searched the internet trying to find the one thing I need to add to the DataTemplate to fix this, but everything I have tried has failed. Here is the code that is NOT working:
<ComboBox Name="cboCit_type"
IsSynchronizedWithCurrentItem="True"
mvvm:View.FlowsWithPrevious="True"
ItemsSource="{Binding Path=cuCodeInfo.CitationTypes}"
SelectedValuePath="code"
Text="{Binding cit_type}"
IsEditable="true"
IsReadOnly="false"
SelectedValue="{Binding cit_type}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Border BorderThickness="0,0,1,0" BorderBrush="Black">
<TextBlock Text="{Binding Path=code}" mvvm:View.WidthEx="2" ></TextBlock>
</Border>
<TextBlock Text="{Binding Path=description}" mvvm:View.WidthEx="15" Margin="1" ></TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Any help will be greatly appreciated.
As an aside, I have to use this exact same format (same list, etc. just different SelectedValue) in a number of forms - so if you want to suggest the best way to do this in xaml, that would be nice. In my pre-xaml days, I would just create a control, set a property or 2, and use that in all my forms. But I am supposed to use xaml, so am not sure of the best way to do this.
Thanks!
I can't believe that I searched all over the net to find an answer and, until now, could not find one. The answer is as easy as I thought it should be.
Just replace:
DisplayMemberPath="code"
with
TextSearch.TextPath="code"
and the code works just fine.
Thanks to all who helped.
I can give you an idea how to use SelectedItem
ViewModel
public class ViewModel
{
public ViewModel()
{
//Suppose your collection CitTypes is Initialized and filled with there Items
//Now you can set first Element as selected in ComboBox
SelectedItem = CitTypes.FirstOrDefault();
}
CitType selectedItem;
public CitType SelectedItem
{
get { return selectedItem; }
set { selectedItem = value; RaisePropertyChanged("SelectedItem"); }
}
}
xaml
<ComboBox Name="cboCit_type"
IsSynchronizedWithCurrentItem="True"
mvvm:View.FlowsWithPrevious="True"
ItemsSource="{Binding Path=cuCodeInfo.CitationTypes}"
Text="{Binding cit_type}"
IsEditable="true"
IsReadOnly="false"
**SelectedItem="{Binding SelectedItem}"**>

Consuming Complex Comboboxes WPF

I want to have complex combobox with checkboxes, text, and may be a thumbnail. I have already looked at the following links which helped me alot while building complex comboboxes.
http://blogs.microsoft.co.il/blogs/justguy/archive/2009/01/19/wpf-combobox-with-checkboxes-as-items-it-will-even-update-on-the-fly.aspx
Looking for a WPF ComboBox with checkboxes
But, I can not find a way to consume these complex usercontol in my application. I am new to WPF, so any kind of demonstration support would be highly appreciated.
Dean, I was looking a solution of how to bind in code behind file with following example mentioned in an SO post earlier.
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}"
Width="20" />
<TextBlock Text="{Binding DayOfWeek}"
Width="100" />
</StackPanel>
</DataTemplate>
So the question is, Do I need DataTable or something else to bind my list of Checkboxes and Titles with this combobox template?
Thanks in Advance
A Combobox is an ItemsControl. All ItemsControls can be filled "hardcoded" with items or containers.
This adds a new entry in the combobox, and wrappes the string into an ItemsContainer, which is a ComboBoxItem.
<ComboBox>
<sys:string>Hello</string>
<ComboBox>
Here we create a combobox item directly, and add its content to a string with the value "Hello"
<ComboBox>
<ComboBoxItem Content="Hello"/>
<ComboBox>
Both look visually the same. Its important to understand that in the first case the ComboBox takes care of wrapping our, to the ComboBox unknown type string, into an ComboBoxItem, and uses a default DataTemplate to display it. The default DataTemplate will display a TextBlock and calls ToString() on the given data item.
Now to have dynamic data, we need a ObservableCollection with our data items.
class Employee
{
public BitmapSource Picture {get;set;}
public string Name{get;set}
}
ObservableCollection<Employee> employees;
myComboBox.ItemsSource = employees;
We have a DataClass called Employee, an observable Collection which holds many of our dataitem, and set this collection as the ItemsSource. From this point on, our Combobox listens to changes to this collection. Like adding and removing Employees and automatically takes care of wrapping the new Employee into a ComboBoxItem. Everything is done automatically. The only thing we need to do is to provide a proper DataTemplate. The combobox doesn't know how to "display" an employee and thats exactly what a DataTemplate is for.
<DataTemplate x:Key="employeeTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Picture}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
We know an employee is wrapped in a ComboBoxItem, and the ComboBoxItem uses a provided Datatemplate to display its data, which means that inside the DataTemplate we can use Binding to access all properties on the data item.
Hope that helps you.
to just answer your question. all you need is a collection of an object with at least 2 public properties (IsSelected as bool and DayOfWeek as string) and just set these collection as the itemssource.
so all you need is a collection of such an object. just comment if you need an example.
ps: pls read through the www for wpf and binding to get the basics.
you could simple add the items directly
<ComboBox>
<ComboBox.Items>
<ComboBoxItem>
<TextBlock Text="test text" />
</ComboBoxItem>
<ComboBoxItem>
<CheckBox Content="test checkbox" />
</ComboBoxItem>
<ComboBoxItem>
<Button Content="test button" />
</ComboBoxItem>
</ComboBox.Items>
</ComboBox>
or if you want to use ItemsSource, the a DataTemplateSelector would be required
<ComboBox>
<ComboBox.ItemTemplateSelector>
<local:MyCustomTemplateSelector />
</ComboBox.ItemTemplateSelector>
</ComboBox>
here is a link that explains DataTemplateSelectors
http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplateselector.aspx

WPF listbox : problem with selection

In my XAML file, I have a ListBox declared like this :
<ListBox x:Name="lstDeck" Height="280" ItemsSource="{Binding Path=Deck}" >
<ListBox.ItemTemplate>
<DataTemplate>
<ListBoxItem Content="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In my view model, Deck is an ObservableCollection, so that binding directly displays the content of my collection.
But when I have several value that hold the same value (for example "10" six times),
the selection in the ListBox has a weird behaviour : it select 2-3 elements instead of the only the one on which I clicked.
Moreover, when I click to another listBoxItem, it doesn't unfocus the previous selected one.
Then it is impossible to see which item is actually selected, and impossible to get the SelectedIndex value.
Has someone an idea?
The problem is that the listbox cannout distinguish between the different values. Therefore, once you click one of the "10"s, it sets it SelectedItem property and updates its presentation. Because it cannot distinguish between the value types it marks every "10" as selected.
But why do you have "10" several times in your listbox? If it is just the numeric value 10 or the string "10" it does not make any sense to me.
If you have a more complex model behind that and you just display one property, than you should bind the complex model and set the DisplayMemberPath instead.
C#
public class Model
{
public Guid Id { get; set; }
public string Value { get; set; }
}
XAML
<ListBox ItemsSource="{Binding Path=Models}" DisplayMemberPath="Value" />
<ListBox ItemsSource="{Binding Path=Models}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Value}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Best Regards
Oliver Hanappi

Resources