I want to use combo box and the following code is working but now I want to
add to the combo box header default value ,i.e. there is value and like
Item and when you open it you have the option to change it,how I can do that?
<ComboBox ItemsSource="{Binding Items}" SelectedValue="{Binding SelectedItem}"
Name="comboBox1" Text="Item" Grid.Column="3" Grid.Row="2" />
the code
private List<String> _items;
private String _selectedItem;
private String _selectedBusinessItem;
public List<String> Items
{
get { return _items; }
set
{
_items = value;
OnPropertyChanged("Items");
}
}
public String SelectedItem1
{
get { return _selectedItem; }
set
{
_selectedItem = value;
OnPropertyChanged("Items");
}
}
private void InitCombo()
{
Items = new List<string> { "item", "Item2", "Item3" };
SelectedItem1 = Items[0];
}
It's hard to understand you are asking, but I think you are just looking for the ComboBox to show the first value in the collection of Items.
I believe you can do this a few ways.
First you need to fix SelectedValue binding to match your property name, and drop the Text="Item":
<ComboBox ItemsSource="{Binding Items}" SelectedValue="{Binding SelectedItem1}"
Name="comboBox1" Grid.Column="3" Grid.Row="2" />
From your code you can set the SelectedValue1 property that you have to any of the string items. Examples of this:
SelectedValue1 = "item";
-or-
SelectedValue1 = Items.FirstOrDefault();
I used FirstOrDefault as a safety incase these items didn't exist.
-or-
SelectedValue1 = Items[0];
And there are several more options here. But I'm going to try and limit the scope of the answer.
Also, you should be able to set the ComboBox.SelectedIndex to 0.
<ComboBox ItemsSource="{Binding Items}" SelectedValue="{Binding SelectedItem1}"
Name="comboBox1" Grid.Column="3" Grid.Row="2"
SelectedIndex="0"/>
I think that you're talking about the ComboBox.Text Property... from the linked page:
Gets or sets the text of the currently selected item
This is not a free field that you can display a message in. It displays the value of the currently selected item from the ComboBox.Items collection. If the text is not in one of the items, then this TextBox 'should' not display that value.
However, there are always workarounds. The correct way to do it would be to define a new ControlTemplate for the ComboBox that contains a TextBlock that is overlayed on top of the selected item TextBox and hidden when required.
Some people think that that is too much work though and so you can find a number of alternative solutions in the How to display default text “--Select Team --” in combo box on pageload in WPF? post here on StackOverflow.
List Items = new List { "item", "Item 2", "Item 3" };
Set the Selected Index = 0, It will select the first element in the combo box Item-source
XAML:
<ComboBox ItemsSource="{Binding Items}"
Name="comboBox1" Grid.Column="3" Grid.Row="2"
SelectedIndex="0"/>
Related
I have a combobox which allows users to select from a collection of images. Because of the size of the images I would like to not display the image in the combobox once an image has been selected. I simply want nothing displayed in the combobox when an item is selected.
So far I have tried setting the selectedImageIndex to -1 once the selectedImageSource has been set when the user makes a selection however this did not work as the first image at [0] is still displayed in the combobox by default. I am using MVVM.
XAML
<ComboBox Grid.Row="1" SelectedIndex="{Binding SelectedImageIndex}" ItemsSource="{Binding SymbolImageCollection}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Img}" Width="50" Height="50"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="300" HorizontalAlignment="Left"/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
View Model
public ObservableCollection<SymbolImage> SymbolImageCollection { get { return AppearanceLayerProperties.Instance.SymbolImageCollection; } }
private string _selectedImageSource;
public string SelectedImageSource
{
get { return _selectedImageSource; }
set
{
SetProperty(ref _selectedImageSource, value);
//SelectedImageIndex = -1;
}
}
private int _selectedImageIndex;
public int SelectedImageIndex
{
get { return _selectedImageIndex; }
set
{
var selectedImage = AppearanceLayerProperties.Instance.SymbolImageCollection[value].ImgSource;
SelectedImageSource = selectedImage;
SetProperty(ref _selectedImageIndex, -1);
}
}
Changing the selection back to null after selecting an item of the ComboBox is not good practice, because if you need to use the selected value, it is not available anymore.
A solution could be to have a different template for the selected item of the ComboBox. That way, you could remove the image, but in its place put something else, like text, so the user as an idea of what item is selected. Here is a previous StackOverflow post explaining how to do this :
Can I use a different Template for the selected item in a WPF ComboBox than for the items in the dropdown part?
I hope this helps!
Please help!
I did many research on the internet, but didn't find any solution for my question.
I have a form with foods. There is a grid on the form and with it I can navigate on the food table. There is a combobox on the screen (not in the grid) which contains the categories. The combobox is filled up with the categories from categories table. When I change the record on the datagrid every field updated on the form except the combobox.
first record
second record
So my question is: what I have to do to refresh the combobox, to show the saved category when I navigate on the grid?
In the category table the category has "id" field and in the food table there is a "categoryid" field.
I have this in the xaml file:
<ComboBox x:Name="categoryComboBox" Grid.Row="5" Grid.Column="1" Margin="3,4,20,0" Grid.ColumnSpan="3"
ItemsSource="{Binding Source={StaticResource categoryViewSource}}"
SelectedValuePath="CategoryId"
DisplayMemberPath="CatName"
SelectedItem="{Binding CategoryId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Height="25" VerticalAlignment="Top">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
As I can see you have a small error in your code. I should use the SelectedValue instead of SelectedItem. So change it and I think it will work properly. And in addition You don't need any workaround with the scaling as I suggested before.
Here is example:
XAML
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" >
<ComboBox x:Name="categoryComboBox" ItemsSource="{Binding Source={StaticResource categoryViewSource}}"
SelectedValuePath="CategoryId"
DisplayMemberPath="CatName"
SelectedValue="{Binding CategoryId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Height="25" VerticalAlignment="Top">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
<Button Content="Change Category" Command="{Binding SelectionChangedCommand}"></Button>
</StackPanel>
DataContext
public class MyComboDataContext:BaseObservableObject
{
private int _categoryId;
private ICommand _selectionChangedCommand;
public MyComboDataContext()
{
CategoryId = 1;
}
public int CategoryId
{
get { return _categoryId; }
set
{
_categoryId = value;
OnPropertyChanged();
}
}
public ICommand SelectionChangedCommand
{
get { return _selectionChangedCommand ?? (_selectionChangedCommand = new RelayCommand(SelectionChanger)); }
}
private void SelectionChanger()
{
CategoryId += 1;
if (CategoryId == 4)
CategoryId = 1;
}
}
Explanations:
First of all, this is an example that is simulating the update of a combo. Here the combobox selected value is changed on each button click. In your example the category selection should effect the combo selected value. So each time the grid category selection happens you should push selected category id into the property the combo SelectedValue is bound to it.
In order to help you please update your question with next things:
Are there any Binding expression errors in your output window?
How do you handle a DataGrid selection in your code.
How the data grid selection effects the combobox SelectedValue(it have to be selected value)?
Let me know if you need more help. And feel free to mark you question as answered if my answer was helpful.
I'm a bit new to the idea of bindings in C#. I currently have an application using MVVM that I'm working on. Say I have, for example, a list like so:
List<string> Items = new List<string>()
{
"Item1",
"Item2",
"Item3",
}
Bound to this list are three textboxes like so:
In the XAML:
<TextBox Name="TextBox1" text="{Binding TextSource1 Mode=TwoWay}">
<TextBox Name="TextBox2" text="{Binding TextSource2 Mode=TwoWay}">
<TextBox Name="TextBox3" text="{Binding TextSource3 Mpde=TwoWay}">
And in the code:
Public string TextSource1
{
get { return Items[0]; }
set { Items[0] = value; }
}
Public string TextSource2
{
get { return Items[1]; }
set { Items[1] = value; }
}
Public string TextSource3
{
get { return Items[2]; }
set { Items[2] = value; }
}
Say the displayed value in the first textbox is currently "Item1" as it is in the list. From here the user changes it to "Item4". How would I update the list from that? Does it update automatically if it's set to TwoWay?
I know in the code if I were to change a value in the list, say:
Items[2] = "Item4";
I can update the textbox by calling
RaisePropertyChanged("TextSource3");
But that's not of much help to me at the moment.
There are a couple of things to note. First when by default, a TextBox won't propagate the text changes until it loses focus. This can happen if you tab out of the control, or click on another control that can receive focus (like the other TextBoxes).
You can change this behavior by setting the UpdateSourceTrigger on the Binding (you also don't need Mode=TwoWay on a TextBox as it is the default mode):
<TextBox Name="TextBox1" text="{Binding TextSource1, UpdateSourceTrigger=PropertyChanged}" />
The second is that your properties need to raise the PropertyChanged event in their setter. While this isn't strictly necessary for a single Binding to work, you will want to do it in case you decide to have other controls bound to the same property.
Change type of Items to ObserableCollection<String>
Change binding of textbox to:
<TextBox Name="TextBox1" text="{Binding Items[0], Mode=TwoWay}">
<TextBox Name="TextBox2" text="{Binding Items[1], Mode=TwoWay}">
<TextBox Name="TextBox3" text="{Binding Items[2], Mpde=TwoWay}">
Because of ObservableCollection's internal notification mechanism, when you modify one of its element, it will notify UI.
Say the displayed value in the first textbox is currently "Item1" as it is in the list. From here the user changes it to "Item4". How would I update the list from that? Does it update automatically if it's set to TwoWay?
Yes it updates automatically when it loss focus.
I have an observable collection bound to a list box.
The collection has 2 items, but the list box is showing 3 items (e.g. the 2 items that are actually in the observable collection and an additional item for the NewItemPlaceholder.
I want it only to show the 2 items.
Below is my XAML.
<ListBox MinHeight="20" MinWidth="20" Name="MultipleSelectionsMultipleWagersListBox" Visibility="{Binding Path=Coupon.BarcodeText, Converter={StaticResource CouponBarcodeToVisibilityConverter1}, ConverterParameter=994450_994550}" Height="AUto" Width="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="5"
ItemsSource="{Binding Path=BetViewModels}" Grid.Row="1" Grid.Column="1" >
<ListBox.ItemTemplate>
<DataTemplate>
<View:BetView DataContext="{Binding}" Name="ThisBet" Margin="5"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here is the c#
private ObservableCollection<BetViewModel> _betViewModels = new ObservableCollection<BetViewModel>();
public ObservableCollection<BetViewModel> BetViewModels
{
get { return _betViewModels; }
set
{
if (Equals(value, _betViewModels)) return;
_betViewModels = value;
OnPropertyChanged("BetViewModels");
}
}
Here is the code to populate the betViewModels:
var betViewModel = new BetViewModel { Bet = new Bet() };
betViewModel.Bet.SelectionName = "Chelsea";
betViewModel.Bet.Price = "4/9";
betViewModel.Bet.Market = "90 Minutes";
betViewModel.Bet.ExpectedOdd = DateTime.Now;
BetViewModels.Add(betViewModel);
betViewModel = new BetViewModel { Bet = new Bet() };
betViewModel.Bet.SelectionName = "Chelsea";
betViewModel.Bet.Price = "4/9";
betViewModel.Bet.Market = "90 Minutes";
betViewModel.Bet.ExpectedOdd = DateTime.Now;
BetViewModels.Add(betViewModel);
How Do I switch of this from showing the additional item for the new item place
Here is an image of it displaying the placeholder
The DataGrid supports adding new rows, which have to start out blank. If your ItemsSource is bound to both a ListBox/ItemsControl and a DataGrid, you need to set the DataGrid 'CanUserAddRows' property to 'False'.
Where I found the answer: http://www.mindstick.com/Forum/1519/How%20do%20I%20remove%20a%20listbox%20new%20item%20placeholder
There's nothing in your code that should be adding an extra empty item. There may be some other code adding to BetViewModels or there may be a change happening to the generated ICollectionView for the collection if you have it bound to something else that you're not showing, like an editable DataGrid.
did your sample code also provide this issue?
how much items contains your _betViewModels.count in debugging there are really only 2 Items?
it seems you added an empty BetViewModel at the End
i would suggest check your logic which provides populates your items
if it is a loop it should (counter<yourDatasource.Count) just for example
I'm a bit puzzled:
this works:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Label Content="Rol" />
<ComboBox ItemTemplate="{StaticResource listRollen}"
Height="23" Width="150"
SelectedItem="{Binding Path=SelectedRol, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
ItemsSource="{Binding Path=allRollen, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
and the property for SelectedRol is:
public TblRollen SelectedRol
{
get { return _selectedRol; }
set
{
if (_selectedRol != value)
{
_selectedRol = value;
OnPropertyChanged("SelectedRol");
}
}
}
But this doesn't work:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Label Content="Soort" />
<ComboBox ItemTemplate="{StaticResource listSoorten}"
Height="23" Width="150"
ItemsSource="{Binding Path=allSoorten}"
SelectedItem="{Binding Path=SelectedProduct, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
with following property SelectedProduct:
public TblProduktSoorten SelectedProduct
{
get { return _selectedPSoort; }
set
{
if (_selectedPSoort != value)
{
_selectedPSoort = value;
OnPropertyChanged("SelectedProduct");
}
}
}
somewhere in my code I set SelectedProduct = p.TblProduktSoorten and while debugging, I see the property gets set correctly...
Combobox inside a DataGrid?
If the combobox is in a DataGrid you must add this :
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged
See this : https://stackoverflow.com/a/5669426/16940
Try to use not selected item but value path look at the code sample
<ComboBox Name="projectcomboBox" ItemsSource="{Binding Path=Projects}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="FullName"
SelectedValuePath="Name" SelectedIndex="0" Grid.Row="1" Visibility="Visible" Canvas.Left="10" Canvas.Top="24" Margin="11,6,13,10">
</ComboBox>
the binding property is
public ObservableCollection<Project> Projects
{
get { return projects; }
set
{
projects = value;
RaisePropertyChanged("Projects");
}
}
This might be related to the fact that apparently attribute order does matter, in your second case the ItemsSource and SelectedItem declarations are swapped.
If you set the SelectedProduct property when SelectedProduct is changed in the property changed event handler, you need to set this property asynchronously.
private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "SelectedProduct")
App.Current.Dispatcher.InvokeAsync(() => SelectedProduct = somevalue);
}
My problem was caused by my own tired brain. Same symptom, maybe it will kick you into seeing your problem.
Setting the SelectedItem must be given an item in the List!! (duhh) Normally this happens naturally but I had a case I got a "Role" from another service (Same object type) and was trying to set it and expecting the combobox to change! ;(
instead of -
Roles = roles;
CurrentRole = role;
remember to do this -
Roles = roles;
CurrentRole = roles.FirstOrDefault(e=> e.ID == role.ID); //(System.Linq)
I don't know if you fixed it yet, but I encountered the same issue today.
It was fixed by making sure the collection for selecteditems was an ObservableCollection.
I think this problem is caused by the type of ItemSource and SelectedItem is mitchmatched.
For example, if the ItemSource is binded to a List of int and the SelectedItem is binded to a string. If you set selected item to null or empty string, the combobox cannot know what item is selected. So the combobox will show nothing.
This might be old but I have not seen the trick that did it for me; I had to add NotifyOnSourceupdate=true to my SelectedItem in the ComboBox
This had me stumped for a while inside a DataGrid, using SelectedItem. Everything was fine but I am deserializing the app state which loads the items and also has a selected item. The collection was there but the selected isn't actually visible until I used the Text="{Binding Path=Score.SelectedResult.Offset}"
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ToolTip="Score offset results"
ItemsSource="{Binding Score.SearchResults,UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding Score.SelectedResult, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding Path=Score.SelectedResult.Offset}"
SelectedValuePath="Offset"
DisplayMemberPath="Offset"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>