I'm displaying all of my customers which I get from a ViewModel ObservableCollectoin property within a ComboBox like this:
<ComboBox
ItemsSource="{Binding Customers}"
ItemTemplate="{StaticResource CustomerComboBoxTemplate}"
Margin="20"
HorizontalAlignment="Left"
SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"/>
Is there a way to get the number of items in the ObservableCollection without creating another ViewModel property, e.g. something like this:
PSEUDO-CODE:
<TextBlock Text="{Binding Customers.Count()}"/>
The ObservableCollection type exposes a Count Property which you can use.
I don't know if ObservableCollection raises the PropertyChanged event in order to inform the UI about updates to this property though.
Related
I am new to WPF:
I have a combobox whose ItemsSource is changing. This is not being reflected back to the user. Do i have to specify the ItemsSource Mode to TwoWay?
Any Suggessions?
<ComboBox Height="Auto" Name="comboBoxQuery" Width="300" IsEditable="True" ItemsSource="{Binding QueryNames, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" SelectedItem="{Binding SelectedQueryNames, Mode=TwoWay}" SelectedValuePath="Key" DisplayMemberPath="Value" Visibility="Collapsed" /> <!--Is this correct? -->
In order to tell the view that collection source was changed, you should use collection classes which supports INotifyCollectionChanged interface. For example: ObservableCollection, BindingList. You do not need TwoWay data binding, WPF will detect that source collection supports INotifyCollectionChanged interface, and all changes you made in that collection will reflect the view.
I can use databinding to bind the contents of a combobox to a collection, or I can bind the selected value in the combobox to a member of a class, but I can't do both at the same time. I want to be able to bind the contents to one thing and the selected value to something else, I guess the combobox can't handle two datacontexts or I'm not specifying them explicitly. Example below, I'd appreciate any help! Thanks.
In XAML:
<ComboBox Name="Combo" ItemsSource="{Binding}"
SelectedValue="{Binding ID, Mode=TwoWay}"/>
In code:
LayoutRoot.DataContext = myClass;
Combo.DataContext = items;
This should do it for you, or at least be close.
<Grid DataContext="{Binding Source=MyObject}">
<ComboBox x:Name="Combo"
ItemsSource="{Binding Source=MyCollection}"
SelectedValue="{Binding Path=ID, Mode=TwoWay}"/>
</Grid>
I am writing what is turning out to be a simple GUI in WPF. At the moment I have a static list inside of a ComboBox, like this:
<ComboBox HorizontalAlignment="Left" Height="22" Margin="24,97,0,0" VerticalAlignment="Top" Width="83"
SelectedItem="{Binding fruit, Mode=TwoWay}">
<ComboBoxItem>apple</ComboBoxItem>
<ComboBoxItem>orange</ComboBoxItem>
<ComboBoxItem>grape</ComboBoxItem>
<ComboBoxItem>banana</ComboBoxItem>
</ComboBox>
I'm binding the SelectedItem to a singleton in my code that has already been initialized and used elsewhere.
I put a breakpoint on the get of fruit and it returns "grape", but the selected item is always blank. I even added a button so that I could call RaisePropertyChanged manually, but the RaisePropertyChange call didn't do anything either.
Finally, MVVMLight gives blendability. For no important reason I changed the binding in the combobox from SelectedItem to Text As soon as I did that, my design time form filled in with the expected values, but, when the code is running, the box continues to sit at the empty state
This is because you have items of type ComboBoxItem in the ComboBox but the property you are trying to bind to is of type string.
You have three options:
1.Instead of adding ComboBoxItem items add String items:
<ComboBox HorizontalAlignment="Left" Height="22" Margin="24,97,0,0" VerticalAlignment="Top" Width="83"
SelectedItem="{Binding fruit, Mode=TwoWay}">
<sys:String>apple</sys:String>
<sys:String>orange</sys:String>
<sys:String>grape</sys:String>
<sys:String>banana</sys:String>
</ComboBox>
2.Instead of SelectedItem bind to SelectedValue and specify SelectedValuePath as Content:
<ComboBox HorizontalAlignment="Left" Height="22" Margin="24,97,0,0" VerticalAlignment="Top" Width="83"
SelectedValue="{Binding fruit, Mode=TwoWay}"
SelectedValuePath="Content">
<ComboBoxItem>apple</ComboBoxItem>
<ComboBoxItem>orange</ComboBoxItem>
<ComboBoxItem>grape</ComboBoxItem>
<ComboBoxItem>banana</ComboBoxItem>
</ComboBox>
3.Do not specify items directly in XAML, but use ItemsSource property to bind to a collection of strings:
<ComboBox HorizontalAlignment="Left" Height="22" Margin="24,97,0,0" VerticalAlignment="Top" Width="83"
ItemsSource="{Binding Fruits}"
SelectedItem="{Binding fruit, Mode=TwoWay}"/>
You should bind ComboBox.ItemSource to a list of strings (make the List of strings an ObservableCollection<string> in case you add items to this list) and then set the fruit variable to an instance in the List of strings.
I think you have your problem because your fruit variable references a different instance than you have in your list of ComboBoxItems. (even though the strings are the same)
I am DataTemplating a listbox's ItemSource to display a series of comboboxes. I want to give the DisplayMemberPath of the combo to a property, which is in a different source than its own ItemsSource. (Assuming DisplayMemberPath is just a string representing name of a property, I am getting this from the user). I have achieved this with a CollectionViewSource, but all the comboboxes are displaying the same list.
What I am expecting to have after data templating is to have comboboxes display,
ComboboxInstance1.DisplayMemberPath = PropertyMapOfEmployee in FilterControls[0]
ComboboxInstance2.DisplayMemberPath = PropertyMapOfEmployee in FilterControls[1]
Is this possible to achieve in XAML ?
Thanks. Mani
UserControl:
<Resources>
<CollectionViewSource x:Key="bindingSource" Source="{Binding BindingItems}"/>
<CollectionViewSource x:Key="FilterSource" Source="{Binding FilterControls}"/>
<DataTemplate DataType="{x:Type CustomTypes:FilterElement}">
<ComboBox ItemsSource="{Binding Source={StaticResource bindingEmp}"
DisplayMemberPath="{Binding Source={StaticResource FilterSource},
Path=PropertyMapofEmployee}" />
</DataTemplate>
<Resources>
---
<DockPanel>
<ListBox x:Name="lstBox" ItemsSource="{Binding FilterControls}" />
</DockPanel>
ViewModel:
List<FilterElement> FilterControls;
List<Employee> Employees
class FilterElement
{
string Caption;
String PropertyMapofEmployee
}
<ComboBox ItemsSource="{Binding Source={StaticResource bindingEmp}"
DisplayMemberPath="{Binding PropertyMapofEmployee}" />
I'm not sure you can do that in XAML. (Having the DisplayMemberPath point to a property that is on an object other than the DataContext). You may want to look at the RelativeSource Class to see if that would meet your needs.
Have you thought about providing a reference in your Employee object to the FilterElement and then hooking up to the binding the Employee.PropertyMapOfEmployee property that you've created?
Why is the first element in my combobox popup menu not shown in the selected item area of
my combobox , when I use the SelectedItem binding? Without that it is showing up ?? Using
the same code selecteditem + selectedindex that is no problem!
<ComboBox
ItemsSource="{Binding SchoolclassSubjectViewModels}"
SelectedItem="{Binding SelectedSchoolclassSubjectViewModel}"
SelectedIndex="0"
Height="23"
HorizontalAlignment="Left"
Margin="375,13,0,0"
VerticalAlignment="Top"
Width="151">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SchoolclassName}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding SubjectName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Well as workaround I used:
SchoolclassSubjectViewModels.Add(schoolclassSubjectVM);
SelectedSchoolclassSubjectViewModel = schoolclassSubjectVM;
and this:
SelectedItem="{Binding SelectedSchoolclassSubjectViewModel,Mode=TwoWay}"
but I would prefer the xaml only way as it should really work.
It is because the reference inside your ItemsSource collection is not the same as the one in your SelectedItem property. I would venture to guess that you are using one object context to query your database for the list of SchoolclassSubject objects which the ItemsSource is bound to, but another context to query the actual data item to which you bind the SelectedItem. Even though the list contains a reference which represents the value held by your object, it is not really the same reference, but a separate instance of the same data.
There are ways to solve this issue, most of them involve using the SelectedValuePath and SelectedValue instead of the SelectedItem properties, but the concrete solution would be different depending on your particular ORM.