How to load Combobox-items on dropdown - wpf

I need to work with an excel workbook, with some worsheets.
To load the available worksheets into a combobox, I need to open the workbook and iterate through all sheets and add them to the combobox. This cost a lot of time, the user needs to wait for. If the user doesn't want to change the preloaded property, this time is waisted. So I only want to fill in the listitems when needed but show the preselected property, that was loaded from a settingsfile on startup of the app.
So is there a way to load the items on dropdown? Or better, how can I bind a command that is triggerd on dropdown, to load the items?
<ComboBox SelectedItem="{Binding Worksheet}" ItemsSource="{Binding WorkSheets}" x:Name="cbWorkSheet" Padding="4">
... oh, I know how to bind a command to a button so I need a special tip for the combobox, not for commands in general :)
UPDATE
I solved to trigger the "loading" and the List is filled but I need to show the last selected value (that is loaded on startup as the bound property Worksheet)
<ComboBox
x:Name="cbWorkSheet"
SelectedItem="{Binding Worksheet}"
ItemsSource="{Binding WorkSheets}"
IsEditable="True"
Padding="4">
<i:Interaction.Triggers>
<i:EventTrigger EventName="DropDownOpened" SourceObject="{Binding ElementName=cbWorkSheet}">
<i:InvokeCommandAction Command="{Binding LoadBACnetWsCombobox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
With that Binding, the Combobox remains empty till I dropdown it :(

Original Answer: Incorrect, Posted 2020/06/02:
If you need SelectedItem populated before you open the dropdown, then you should probably change your EventTrigger's EventName from DropDownOpened to be Loaded.
That way, before the combobox is shown to the user, LoadBACnetWsComboBox will run, and hopefully your Worksheet will be set. Then, the combobox will be shown to the user.
Modified Answer, Posted 2020/06/03:
If you want to just populate the initial displayed text, you can always set the Text property of the combobox. It will get overridden once you do selections from the drop down.
<ComboBox
...
Text="{Binding MyInitialValue}">

Related

Combobox: Get text and selected item in mvvm way

The combobox is editable so user can also write. I have two usecases:
Get the text from combobox in a Lostfocus way, when user writes
something in the box and when he presses "Tab" then I want the text
from the combobox and I add the value in the itemsSource list.
When the users makes the selection from the combobox dropdown, I want that
selected item as soon he selects it and this time I dont
want to have it in Lostfocus manner but somewhat like
PropertyChanged way.
I tried the code which is given below:
<ComboBox Margin="3" x:Name="Combobox" SelectedItem="{Binding SelectedPath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Text="{Binding PathLocation, UpdateSourceTrigger=LostFocus, ValidatesOnNotifyDataErrors=True}" IsTextSearchEnabled="True" VerticalContentAlignment="Center" ItemsSource="{Binding SelectedPaths}" IsEditable="True" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" HorizontalAlignment="Stretch"/>
Things worked fine for the first time when the application starts but after some interactions the problem arises. When the user starts typing in the combobox the SelectedItem property of combobox triggers which is contrary to what I want in the first use case.
In short: when the user writes something in the combobox I want to have it in a Lostfocus manner and when he makes the selection from the dropdown of combobox I want to have it in a PropertyChanged manner.
Let me know if more details are required.
I removed the "IsTextSearchEnabled" property but it also didnt work then I came to know that "IsTextSearchEnabled" property of Comobobox is by default true, which is causing some values suggested by the combobox are setting in my properties. As soon as I made the "IsTextSearchEnabled" to false, it is working fine.

Trying to get the currently selected item from a ComboBox DataTemplate inside a DataGrid off an DropDownClosed Event Handler

I previously had a ListView that was displaying an ObservableCollection of "Player" object properties, which I'm trying to convert into a DataGrid. I have most of it working, but currently having some issues with seeing changes on one particular property (Status), which is represented by a ComboBox. The idea is to allow players to override the "Status" value between a set of enums representing things like "Alive, Dead, Poisoned," etc. I've hooked up an EventHandler for when the ComboBox is closed and inside that handler, try to grab the sender object as a Player so I can send out the valid player values.
Here's a snippet of the XAML where I'm creating the ComboBox via a DataTemplate.
<DataGridTemplateColumn Header="Status">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Name="cbStatus"
ItemsSource={Binding Source={StaticResource statusTypes}}"
SelecteItem="{Binding statusType, Mode=TwoWay}"
DropDownClosed="cbStatusType_DropDownClosed"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
Inside the Event Handler, I'm using the following to try and grab an "Player" object based on the values coming back from that particular row of the GUI.
Player playerOverridden = (Player)(sender as FrameworkElement).DataContext;
However, when I'm debugging the new playerOverridden when the ComboBox closes and a new value is selected, I'm not seeing that value being captured in playerOverridden.
This is pretty much the exactly what I was doing in a ListView with GridViewColumn.CellTemplates and it was working just fine. Not sure why the Status value is coming back as whatever it was initially set to instead of what the player has selected from the ComboBox.
Had to set the UpdateSourceTrigger on the SelectedItemBinding to be PropertyChanged, it works. Not sure why this has to be set explicitly inside a DataGrid where it's not something I needed to do in the ListView.
SelectedItem={"Binding statusType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

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.

Set WPF CheckBox in a ComboBox to Checked

I have a custom WPF control - essentially a combo-box with check-boxes. The combo-boxes are successfully bound to a list of available items.
This control is to represent a field on a form. It is possible for the form to be completed already, in which case, the control must be rendered with the selected items - i.e. any items previously selected must be rendered as a checked CheckBox; it is here I'm running into trouble.
My first thought was to simply bind the IsChecked property - I don't think this can be done as the list of currently-selected-items is different from the list of available items which the ComboBox is bound to.
Basically, how do I gain access to the CheckBox object to set the Checked property to true? I've looked into this extensively and I can't fathom this out.
I'm using the ItemContainerGenerator approach - so when the user clicks on the drop-down, it is intended that a handler will iterate through the CheckBoxes and set the relevant boxes to checked.
Here's the XAML:
<ComboBox x:Name="FieldOptions"
ItemsSource="{Binding}"
HorizontalAlignment="Stretch"
Height="30"
KeyDown="FieldOptions_OnKeyDown">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Name="checkbox"
Content="{Binding Path=Text}"
Uid="{Binding Path=ID}"
FontStyle="Normal"
Foreground="Black"
Checked="CheckBox_OnChecked" />
</DataTemplate>
</ComboBox.ItemTemplate>
Any thoughts would be much appreciated.

Why is my ComboBox SelectedItem null?

I have a WPF/MVVM (using MVVM-Light) app setup with a ComboBox that is inside a DataTemplate. The XAML of the ComboBox looks like this:
<ComboBox x:Name="cbTeachers"
Grid.Column="1"
Style="{StaticResource ComboBox}"
ItemsSource="{Binding Teachers}"
Grid.Row="3"
DisplayMemberPath="Name"
SelectedValuePath="Id"
IsSynchronizedWithCurrentItem="False"
SelectedItem="{Binding Path=SelectedTeacher}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding TeacherSelectedCommand}"
CommandParameter="{Binding SelectedItem, ElementName=cbTeachers}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
The Teachers property for the ItemsSource is a type called ObservableRangeCollection and is based on the code found here: http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx, but it's very similar to a standard ObservableCollection. The SelectedTeacher property is set when another property is set and the code looks very similiar to this:
this.SelectedTeacher = (from t in this.Teachers where t.Id == this.DataItem.Teacher.Id select t).Single();
The problem I am running into, which makes zero sense to me, is SelectedTeacher is getting reset to null once I set it. I can step through the debugger and see SelectedTeacher has a value and when I put a breakpoint on the setter for the property it definitely has the value. But then that property gets hit again with a null value. I checked the call stack and it showed the only preceeding line as being External Code (which makes sense since I only set that property in one place and it only gets hit once, as expected). Expanding the External Code option in the call stack window shows the typical WPF call stack of maybe 40 methods so it's definitely internal to WPF and not something I am doing to make it reset. In fact, when I remove the SelectedItem="{Binding SelectedTeacher}" the setter for that property doesn't get called a second time (thus it retains its value), but of course the ComboBox doesn't show the selected item either. I tried implementing a SelectedIndex option in my viewmodel but that didn't work either. The ComboBox just won't select the item. I can change the selected item in the ComboBox just fine, but the initial setting won't take.
Any ideas? Based on everything I've searched it might be related to me using a DataTemplate, but I have to because that template is part of a parent ContentTemplateSelector implementation.
As a side note, I have multiple properties that bind to controls in this DataTemplate and this is the only one that doesn't work. The others work perfectly. I have also tried the ComboBox with and without the "IsSynchronizedWithCurrentItem" flag and it made no difference.
have you tried to remove to EventTrigger stuff and just to use
SelectedItem="{Binding Path=SelectedTeacher, Mode=TwoWay}"
with Mode=TwoWay?
its not clear to me what you want to achieve with your EventTrigger?

Resources