ComboBox default value? - c#

I'm writing a Windows Store app and I need a ComboBox to have its default value. I also would like to know which item from the list the user selects but I can't find out how to do it. I tried different properties but with no results. Any ideas about doing this?
The code I have for create the ComboBox is:
<ComboBox x:Name="cboxelemento" Width="350" ItemsSource="{Binding}"
SelectionChanged="cboxelemento_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="lnombre" Text="{Binding Nombre}" FontSize="24"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.DataContext>
<Clases:Datos/>
</ComboBox.DataContext>
</ComboBox>

private void cmbox_SelectedValueChanged(object sender, EventArgs e)
{
var val = cmbox.SelectedValue;
//or
//cmbox.Selectedindex;
}
you can access the value like this

First you must use the SelectedValueChanged Event.
private void cmbox_SelectedValueChanged(object sender, EventArgs e)
{
if (cmbox.Focused)
{
//do
}
}
The property Focused goes to true when you have clicked on the ComboBox.

Related

How do I handle SelectionChange when the ComboBox is

I have a ListBox, where the list element has a ComboBox, a TextBox and a slider. Depending on the selction of the ComboBox either the TextBox or the slider should be visible.
<ListBox Name="lstPWM" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<!-- more definitions -->
</Grid.ColumnDefinitions>
<ComboBox ItemsSource="{Binding Path=Gebertyp, Converter={local1:EnumToCollectionConverter}, Mode=OneTime}"
SelectedValuePath="Value"
DisplayMemberPath="Description"
SelectionChanged="PWMTyp_SelectionChanged"
SelectedValue="{Binding Path=Gebertyp}" />
<TextBox Visibility="{Binding GeberVisible}" Text="{Binding GeberNmr, Mode=TwoWay}"/>
<Slider Visibility="{Binding WertVisible}" Value="{Binding Wert, Mode=TwoWay}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The code behind is:
public partial class MainWindow : Window
{
public ObservableCollection<PWMKanal> PWM_col { get; set; } = new();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
lstPWM.ItemsSource = PWM_col;
foreach (var item in Board.PWM) PWM_col.Add(item); //Board.PWM is the data source.
}
private void PWMTyp_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox box = sender as ComboBox; // Finding the line in the ListBox.
PWMKanal PWM = box.DataContext as PWMKanal;
int z = PWM_col.IndexOf(PWM);
Board.PWM[z].Gebertyp = (QuellePWM)box.SelectedValue;
if (Board.PWM[z].Gebertyp == QuellePWM.Sender)
{
PWM_col[z].GeberVisible = Visibility.Visible; // I thought that i may change the
PWM_col[z].WertVisible = Visibility.Hidden; // ObservableColelction directly
} // but the display is not updated.
else // In Debug mode i see, that PWM_coll
{ // is changed as expected, but no effect
PWM_col[z].GeberVisible = Visibility.Hidden; // on the GUI.
PWM_col[z].WertVisible = Visibility.Visible;
}
if (PWM_col.Count != 0) // this code is intended to update the GUI, but every time
{ // a new item is added the Selection Change fires again
PWM_col.Clear(); // and i get a stack overflow in an endless loop.
foreach (var item in Board.PWM) PWM_col.Add(item);
}
}
}
The comments describe my approaches and problems:
I change the selected element of the ObservableCollection directly, but this has no effect on GUI. At least tho code doesn't crash.
I clear the list ObservableCollection PWM_col, but then i get an infinite loop: every time an element is added to the list the SelectionChange event fires, calling the routin again. Result is stack overflow.
Now my questions to my approaches:
Is it possible to change an element of an ObservableCollection directly by code, and the display is automatically refreshed?
Is it possible to somehow catch the SelectionChanged event before the handler is executed? Or is it possible to temporary dissable the event?
Any other idear?
Thank you for your help!
CollectionChanged does notify, that collection itself, not the
single items, is changed. Therefore to see the changes item's
property need to implement INotifyPropertyChanged. Also remove Mode=OneTime
You can of course set the flag, that PWMTyp_SelectionChanged is
running:
private bool selChangedIsRunning = false;
private void PWMTyp_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(selChangedIsRunning) return;
selChangedIsRunning = true;
// do stuff ....
selChangedIsRunning = false;
}
Other idea is - don't use the SelectionChange event, but do bind
Slider.Visibility and TextBox.Visibility to the
ComboBox.SelectedValue and use value converter to define the
Visibilty, also you can use the ConverterParameter.
<ComboBox x:Name="CmbPWMTyp" ItemsSource="{Binding Path=Gebertyp, Converter={local1:EnumToCollectionConverter}, Mode=OneTime}"
SelectedValuePath="Value"
DisplayMemberPath="Description"
SelectionChanged="PWMTyp_SelectionChanged"
SelectedValue="{Binding Path=Gebertyp}" />
<TextBox Visibility="{Binding ElementName=CmbPWMTyp, Path=SelectedValue, Converter={StaticResource YourConverter}, ConverterParameter=TBX}" Text="{Binding GeberNmr, Mode=TwoWay}"/>
<Slider Visibility="{Binding ElementName=CmbPWMTyp, Path=SelectedValue, Converter={StaticResource YourConverter}, ConverterParameter=SLDR}" Value="{Binding Wert, Mode=TwoWay}"/>
This link can be also very helpful for you: Difference between SelectedItem SelectedValue and SelectedValuePath

selected value cannot be set

I have a combobox which gets its Items from some scan function.
If the user select an element, in the next time, the user's chosen item should be selected (if it is present on the scan function output). The problem is that I cannot select it.
Here is the declaration of the ComboBox:
<ComboBox Grid.Column="1" Grid.Row="0" Margin="5" Name="SerialPortNames" Text="{Binding Name}" IsEditable="False"/>
and here what I have tried so far:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string portNameSetting = Settings.Default["SerialPortName"].ToString();
SerialPortNames.ItemsSource = SerialPort.GetPortNames();
foreach (string SerialPortNameItem in SerialPortNames.Items)
{
if (SerialPortNameItem == portNameSetting)
{
SerialPortNames.Text = SerialPortNameItem; // why this is not working
break;
}
}
}
by debugging this, I get the item selected in the combobox, but it seems that something override it and it is empty!
In your code you Binded the Text propery and also setting it from code behind
Remove Text="{Binding Name}" from the combobox
<ComboBox Width="200" Height="200" Grid.Column="1" Grid.Row="0" Margin="5" Name="SerialPortNames" IsEditable="False"/>

UWP Get Clicked Item in DataTemplate

I'm sure this has been asked before, however I cannot find the appropriate answer.
I am using an ItemTemplate to display a list of users, this list consists of StackPanels with user details. How can I get the user object that I clicked on?
Current code:
<GridView Name="usersList">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel PointerPressed="UserClicked">
<TextBlock Text="{Binding Forename}"/>
<TextBlock Text="{Binding Surname}"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
This is being populated via an async API call:
usersList.ItemsSource = null;
var task = Users.UserAsync<User>();
usersList.ItemsSource = await task;
How can I capture the User object that has been clicked on PointerPressed?
Like this:
private void UserClicked(object sender, PointerRoutedEventArgs e)
{
User clickedOnUser = (sender as StackPanel).DataContext as User;
}
This approach is more direct than the one using usersList.SelectedItem, so I recommend sticking with it. E.g., it will work if you set SelectionMode="None" for the GridView, whereas the approach based on usersList.SelectedItem won't.
Also, as Sean O'Neil rightfully noticed, you might want to use Tapped event instead of PointerPressed for the most general case scenario.
Use GridView.SelectedItem to reference the object you want when you click on it.
private void UserClicked_PointerPressed(object sender, PointerRoutedEventArgs e)
{
var whatYouWant = usersList.SelectedItem;
}

How do I handle a selected item of LongListMultiSelector?

I have list of items in LongListMultiSelector - how to handle a selected item?
My LongListMultiSelector xaml:
<tkit:LongListMultiSelector Name="longlist" SelectionChanged="longlist_SelectionChanged">
<tkit:LongListMultiSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" FontSize="32" Tap="TextBlock_Tap"/>
</DataTemplate>
</tkit:LongListMultiSelector.ItemTemplate>
</tkit:LongListMultiSelector>
TextBlock tap event handler code:
private void TextBlock_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var itemTapped = (sender as FrameworkElement).DataContext as Book;
}
LongListMultiSelector SelectionChanged event handler code:
private void longlist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
I found part of solution here, however, The problem if at least one item is selected, then textblockTap event doesn't handle - longlist_SelectionChanged event handles everything. How can i fix that?
Once you are using LongListMultiSelector, the SelectionChanged event is fired when item is added or removed. If you want to perform the action regardless item is added/removed, I've managed to do it like this (for a simle string):
private void longlist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string selectedItem = String.Empty;
if (e.AddedItems.Count > 0) selectedItem = e.AddedItems[0] as string;
else selectedItem = e.RemovedItems[0] as string;
MessageBox.Show(selectedItem); // do your work
}
It should run while items are selected separately by tapping, but this method will have problems when more items are added/removed at the same time - if you need it, then you should handle this also.
Your XAML DataTemplate.
<DataTemplate x:Key="listItemTemplate">
<StackPanel Orientation="Horizontal" Margin="4,4">
<TextBlock Tap="textblockTap" Margin="0,-7,0,0" Text="{Binding Name}" Style="{StaticResource PhoneTextLargeStyle}"/>
</StackPanel>
</DataTemplate>
In your CS page;
private void textblockTap(object sender, EventArgs e)
{
var file = (TextBlock)sender;
var ContentFile = (string)file.Text;
MessageBox.Show(ContentFile);
}
This example will show you the text of the selected item in the MessageBox.

WP7 ListBox selected item is not changing the color

I have a ListBox in app, it has an image and textbox inside. I want to set 2 colors and 3rd one for selected item.
<ListBox.ItemTemplate>
<DataTemplate x:Name="Template1">
<StackPanel Orientation="Horizontal" >
<Image Width="100" Height="100" Source="{Binding SmallImage}"></Image>
<Grid>
<TextBlock Text="{Binding Caption}" Foreground="{Binding txtColor}"></TextBlock>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
when I'm changing the foreground color, then the selected item doesn't highlights (I kept it by default).
I tried to add an event to ListBox,
private void DList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBoxItem selectedItem = DList.SelectedItem as ListBoxItem;
selectedItem.Foreground = new SolidColorBrush(Colors.Red);
}
but it shows an exception:
NullReferenceException
"Use the "new" keyword to create an object instance"
If you're going to handle the SelectionChanged event, then you might as well use the SelectionChangedEventArgs object:
private void DList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedDataObject = e.AddedItems[0]; // assuming single selection
ListBoxItem selectedItem =
ListBoxName.ItemContainerGenerator.ContainerFromItem(selectedDataObject);
selectedItem.Foreground = new SolidColorBrush(Colors.Red);
}

Categories