I have a DataGrid with a combobox assigned of Customer IDs, Each Customer ID may have many Account IDs which are assigned in their own combo box. All I want to do is, when a user selects a Customer ID from the combobox, the Account IDs are then updated with the specific CustomerID that was chosen.
I think I am nearly there with the code.
Here I have the itemsource of the customerId applied inside the combobox elementstyle. As you can see I have a property of SelectedItem when an Item is selected from the customer box.
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource"
Value="{Binding DataContext.EntityCollection,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window}}"/>
<Setter Property="DisplayMemberPath" Value="Name"/>
<Setter Property="SelectedItem" Value="{Binding SelectedItem}"></Setter>
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
</Style>
</DataGridComboBoxColumn.ElementStyle>
So inside the Combobox of the Account Id, I am not sure where to put the SelectedItem.AID code...
I have put it inside the SelectedValueBinding property in the first line, but it doesnt work. do I need to put SelectedItem inside the Itemsource porperty inside the EditingElementStyle tag?
<DataGridComboBoxColumn SelectedValueBinding="{Binding SelectedItem.AID}" SelectedValuePath="SID" Header="SID" Width="70">
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource"
Value="{Binding DataContext.EntityCollection,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window}}"/>
<Setter Property="DisplayMemberPath" Value="AID"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource"
Value="{Binding DataContext.EntityCollection,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window}}"/>
<Setter Property="DisplayMemberPath" Value="AID"/>
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
</Style>
</DataGridComboBoxColumn.ElementStyle>
However I could be way off, so any help I would be grateful.
Thanks
<Setter Property="ItemsSource" Value="{Binding DataContext.EntityCollection,
I'm not entirely sure if that is possible, though I would not recommend using that this way.
Bind your ViewModel in the code behind to the DataContext of your View. Now you can bind the ItemsSource to any ObservableCollection Property in your ViewModel. That'd probably be your EntityCollection
Well, when using a DataGridComboBoxColumn, all you need to do, is to tell this column where the data is located by binding the target property.
If you'd have a list of Customer applied to your DataGrid and your property is named ID, your markup might be as follows:
SelectedValueBinding="{Binding ID, Mode=TwoWay}"
Checking the Mode is highly required in order to transmit changes made to your property.
Now, to apply any changes to your other ComboBox, e.g. adding or creating items, you need to use another ObservableCollection and bind it to that second Combobox. If you done that, you can control the items of the second ComboBox when any changes are made to the first one.
Just a short sample how this might look:
private uint _ID;
public uint ID
{
get { return _ID; }
set
{
if (_ID == value) return;
_ID = value;
NotifyOfPropertyChange("ID");
// Do something with your second ComboBox.
// You could create another ObservableCollection and bind that to your second ComboBox and add some items representing the Account IDs
}
}
Don't forget to notify your View when making changes.
If that wasn't the answer you are looking for, please be more specific. Your actual question was very hard to read, I only understood the first paragraph and explained, how you can archive what you want to do.
Related
I've a combobox like this:
<ComboBox x:Name="CountryMenuComboBox"
ItemsSource="{Binding Countries}">
<ComboBox.ItemContainerStyle>
<Style>
<Setter Property="IsEnabled" Value="{Binding IsRemoving}" />
</Style>
</ComboBox.ItemContainerStyle>
what I need to do is enable or disable the items inside the combobox using the property IsRemoving, but this property isn't located inside the itemsource Countries, so I need to access outside the itemsource. How can I do this for a style?
Is IsRemoving a property of the parent viewmodel that owns the Countries property? If so, try <Setter Property=“IsEnabled” Value=“{Binding DataContext.IsRemoving, RelativeSource={RelativeSource AncestorType=ComboBox}}” />
I have a treeview that need to refresh due to data changes. Is it
possible to refresh and select the last node that they were viewing when the tree view was been populated once again?
Thanks for any help.
For auto refresh you can create some ViewModel for treeView. Something like in my answer Binding a WPF TreeView to multiple Lists . To update selected item and expand it you should define in ViewModel IsSelected and IsExpanded properties (like Name property, but bool). And you should define ItemContainerStyle in your TreeView like this.
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</TreeView.ItemContainerStyle>
I have a ListBox having ComboBoxes as ListItems. The ComboBox in each ListItem is created using ListBox's ItemTemplate.
Now, suppose I have 5 ListItems. i.e. 5 ComboBoxes.
For the 1st ListItem i.e. 1st ComboBox I would like to have all the Items from database as ItemsSource.
For the 2nd ListItem i.e. 1st ComboBox I would like to have all the Items from database as ItemsSource.
For the 3rd ListItem i.e. 1st ComboBox I would like to have only the selected Items from above Comboboxes as ItemsSource.
For the 4th ListItem i.e. 1st ComboBox I would like to have only the selected Items from above Comboboxes as ItemsSource.
For the 5th ListItem i.e. 1st ComboBox I would like to have only the selected Items from above Comboboxes as ItemsSource.
So, I think I have to use different DataSource for different ComboBoxes.
And for that to happen I have the following starting code:
<ComboBox....>
<ComboBox.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="ParentListBox.SelectedIndex" Value="0">
<Setter Property="DataSource" Value="{Binding Path=ListCorrespondingToValue1}"/>
</DataTrigger>
<DataTrigger Binding="ParentListBox.SelectedIndex" Value="Non-0">
<Setter Property="DataSource" Value="{Binding Path=ListCorrespondingToValue2}"/>
</DataTrigger>
</Style.Triggers>
</Style>
<ComboBox.Style>
</ComboBox>
Now, my question is what should I use insead of ParentListBox.SelectedIndex in the above code and what should I replace Non-0 with?
You don't use a DataTrigger for the non zero part... you just set it as a Setter in the Style, so that becomes the default value and then the DataTrigger changes the DataSource property only when the value is 0. Try this:
<ComboBox....>
<ComboBox.Style>
<Style>
<Setter Property="DataSource" Value="{Binding
Path=ListCorrespondingToValue2}"/>
<Style.Triggers>
<DataTrigger Binding="ParentListBox.SelectedIndex" Value="0">
<Setter Property="DataSource" Value="{Binding
Path=ListCorrespondingToValue1}"/>
</DataTrigger>
</Style.Triggers>
</Style>
<ComboBox.Style>
</ComboBox>
I have a ComboBox, bound to a DataTable. The ComboBox displays a list of values, pulled from the "wellId" column of the DataTable. The ComboBox is also styled so that I can insert a custom item into the list simply by adding a dummy row to the DataTable with the wellId field set to "(settings)".
<ComboBox IsEditable="True" Name="comboWell" ItemsSource="{Binding}">
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Content" Value="{Binding wellId}" />
<Style.Triggers>
<DataTrigger Binding="{Binding wellId}" Value="(settings)">
<Setter Property="Content" Value="Customize..." />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
For the most part, this works great. It shows the list, and all items (including the dummy items) are selectable in the drop-down list.
However, after selecting an item from the list, whether it is a real item or a dummy item, the ComboBox doesn't show the selected item properly. Rather than showing the same value displayed in the drop-down list (the "wellId" column from the DataTable), it instead just displays the string "System.Data.DataRowView". No matter what I select, it always displays the same thing.
If I specifically set the DisplayMemberPath on the ComboBox to "wellId", then it displays the selected item properly. However, this messes up all of the other styling I have applied, resulting in the drop-down list being filled with blank entries.
How do I get the ComboBox to display the selected item properly?
Change your ComboBox to set the ItemTemplate instead of the ItemContainerStyle, and remove IsEditable=True. If IsEditable=True then the SelectedItem will get displayed in a TextBox, and if a TextBox.Text is bound to an item, it will display the .ToString() of that item
<ComboBox Name="comboWell" ItemsSource="{Binding }">
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Content" Value="{Binding wellId}" />
<Style.Triggers>
<DataTrigger Binding="{Binding wellId}" Value="(settings)">
<Setter Property="Content" Value="Customize..." />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Unless I add DisplayMemberPath on the combobox it does not work. I think it should take it from Style?
I have the comboBox initially disabled. I see it can work when I open another tab with same DataTemplate. Once it works on one instance, it imdly starts working on all. Is is anything to do with tabs?
<Style x:Key="CollectionList" TargetType="ComboBox">
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="IsEditable" Value="True"/>
<Setter Property="IsSynchronizedWithCurrentItem" Value="False"/>
<Setter Property="DisplayMemberPath" Value="Name"/>
</Style>
<ComboBox ItemsSource="{Binding Items}"
Style="{StaticResource CollectionList}"
SelectedItem="{Binding Model.SelectedItem}" />
Change your Style="{StaticResource CollectionList}" to a DynamicResource
I am guessing it has something to do with the StaticResource getting loaded once, and the TabControl items getting loaded as needed