I have a ComboBox in my code, I am trying to get the value of the selected item and write it in a TextBlock. while running the code i get An exception of type 'System.NullReferenceException'. What am i doing wrong?This is my Design
<StackPanel Orientation="Horizontal" >
<ComboBox SelectionChanged="ComboBox_SelectionChanged">
<ComboBoxItem Content="First" IsSelected="True"/>
<ComboBoxItem Content="Second"/>
<ComboBoxItem Content="Third"/>
</ComboBox>
<TextBlock Name="comboResult" />
</StackPanel>
and this is my code
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox cb=(ComboBox)sender;
ComboBoxItem cbi = (ComboBoxItem)cb.SelectedItem;
comboResult.Text = cbi.Content.ToString();
}
Remove the IsSelected property from the ComboBoxItem and it works. You can then set ComboBox.SelectedIndex after initialization. I'm not familiar with how XAML renders, but I think that it's triggering the SelectionChanged event before the TextBlock renders. This can be observed by using a Grid with columns rather than a StackPanel, and putting the TextBlock first in the XAML (but in a higher column than the ComboBox); it works just fine. Additionally, if you catch the TextBlock's Loaded event, you can see that the SelectionChanged event is being hit first in your original code.
Related
I have a combobox in WPF. I put the TextBox in it as ComboBoxItem. Now I want the ComboBoxItem to be filtered when I type in TextBox:
<ComboBox Grid.Column="1" Grid.Row="1" Margin="23,8,22,29" Name="comboBox1" DropDownOpened="comboBox1_DropDownOpened">
<ComboBoxItem>
<TextBox Name="texcombo" Width="90" Foreground="Gray" GotFocus="texcombo_GotFocus" KeyDown="texcombo_KeyDown" TextChanged="texcombo_TextChanged" >جستجو</TextBox>
</ComboBoxItem>
<ComboBoxItem>سلام</ComboBoxItem>
<ComboBoxItem>خوبی</ComboBoxItem>
<ComboBoxItem>عرض ادب</ComboBoxItem>
<ComboBoxItem>سپاسگذارم</ComboBoxItem>
<ComboBoxItem>مرسی</ComboBoxItem>
</ComboBox>
How can i do this?
the way you are implementing the Textbox inside ComboBox is wrong. First of all, you should change the Combobox default template to show a specific Textbox inside it instead of putting the Textbox inside items. Then you should bind an observable collection (for data) to ComboBox items. Now you can filter the ObservableCollection based on TextBox TextChanged event or command.
When a user selects an option in a combobox, I don't want them to select another until the rest of the process is complete.
cmbxTest.isEnabled = false;
I've also tried:
cmbxTest.isReadOnly = true;
But that doesn't appear to do anything; I can still select from the ComboBox.
Disables the ComboBox so this works, but I want to put up a message to the user notifying them of this fact so they don't wonder why they can't select another item from it.
I've tried most of the button events for mouse click, this is an example:
private void cmbxTest_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (!cmbxTest.IsEnabled)
MessageBox.Show("Cannot select another column until this transformation is accepted.");
}
I'm not assuming that isEnabled removed all mouse clicks from the object. Does anyone know how I could still capture a mouse click after the ComboBox is disabled? I figured I could do a check on SelectedItemChange to see if the process is started then throw a warning at that point. But I'm curious if there is a better way.
You cannot capture any source of input on a disabled element. As mentioned in the docs
Elements that are not enabled do not participate in hit testing or focus and therefore will not be sources of input events.
You can however either show a tooltip using ToolTipService.ShowOnDisabled="True".
Or you can wrap your Combobox inside another element or put a mouse down event on an existing parent element and use that to show a message to the user.
<Border MouseDown="Border_MouseDown">
<ComboBox Name="cmbxTest"/>
</Border>
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
if (!cmbxTest.IsEnabled)
MessageBox.Show("Cannot select another column until this transformation is accepted.");
}
Set the combo box to IsEditable="False" and hook the PreviewMouseDown event.
<ComboBox
Width="100"
Height="30"
PreviewMouseDown="ComboBox_PreviewMouseDown"
IsEditable="False">
<ComboBoxItem Content="Coffee" />
<ComboBoxItem Content="Tea" />
<ComboBoxItem Content="Orange Juice" />
<ComboBoxItem Content="Milk" />
<ComboBoxItem Content="Iced Tea" />
<ComboBoxItem Content="Mango Shake" />
</ComboBox>
private void ComboBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var combo = sender as ComboBox;
if (combo == null) return;
if (!combo.IsEditable)
{
MessageBox.Show("Cannot select another column until this transformation is accepted.");
e.Handled = true;
}
}
As an added bonus, this approach causes the combo box's tooltip to function, so if you're so inclined, you can avoid the expense of a message box and simply set the tooltip text.
I have a ComboBox as specified below:
<ComboBox Height="31" Margin="7,7,0,0" Name="callerID" IsEditable="True" Background="LightBlue" KeyDown="callerIDbar_KeyDown" Foreground="White" FontSize="17" FontWeight="Bold" HorizontalContentAlignment="Center" VerticalAlignment="Top" Grid.Row="0" Grid.Column="0" />
storedCalls is a collection of phone numbers that will be populated to the ComboBox.Items:
foreach (string call in storedCalls)
{
if (call != "Enter a number to dial")
callerID.Items.Add(call);
}
All this works fine. I populate the Items primary because I like the autocomplete that is driven by the values in the ComboBox's Items collections. Is there a way the XAML to disable the drop down error, and disable the drop down menu? I.e. make a simple auto complete textbox like control?
I have seen full on TextBox controls that include a bunch of code-behind and complicated markup, and this is not what I am looking to do. I just need to disable the ability of the drop down menu from showing.
You can handle the DropDownOpened event and then close it.
So in n the XAML you get:
<ComboBox x:Name="cb" DropDownOpened="cb_DropDownOpened"/>
And in Code Behind:
private void cbCategoria_DropDownOpened(object sender, EventArgs e)
{
ComboBox cb = sender as ComboBox;
cb.IsDropDownOpen = false;
}
I prefear this solution reather than set MaxDropDownHeight to 0.
Your choice.
I'm new to WPF/C#, and I'm trying to create a simple sql query application to get used to it. I have a listbox and a corresponding button in my XAML:
<ListBox Name="dbTables" Grid.Column="1" Grid.Row="2">
<ListBoxItem>Log</ListBoxItem>
<ListBoxItem>DownloadRequest</ListBoxItem>
<ListBoxItem>EmailRequest</ListBoxItem>
</ListBox>
<!-- View report button -->
<Button x:Name="myButton" Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125" Height="25" HorizontalAlignment="Right" Click="Button_Click">View</Button>
and the corresponding C# function:
private void Button_Click(object sender, RoutedEventArgs e)
{
String curItem = dbTables.SelectedValue.ToString();
Console.WriteLine("CurItem = " + curItem);
Results resultsPage = new Results(curItem);
this.NavigationService.Navigate(resultsPage);
}
However, when it outputs the CurItem it has this value:
CurItem = System.Windows.Controls.ListBoxItem: Log
Which then throws an exception when I try to run a SQL Query. I'm trying to get it to just be
CurItem = Log
I've tried several different ways but I can't seem to just get the name of the selected value without the object definition attached.
SelectedItem returns the currently selected item in the list box. Since you're populating your list box with ListBoxItems, that's what it will return. (Note, by the way, that your list box automatically generates ListBoxItem containers for its items - if you look in the visual tree, you'll find that this ListBox contains ListBoxItems, each of which contains a ListBoxItem. SelectedItem contains the content of the generated ListBoxItem, which is to say the ListBoxItem you're creating in markup.)
SelectedValue returns the value of the property of SelectedItem that is specified by ListBox.SelectedValuePath. If no SelectedValuePath is given, it returns SelectedItem, so if you don't know about SelectedValuePath, it seems like the two are the same thing. But if you populate your list with, say, Person objects, and set SelectedValuePath to "Name", the SelectedValue will contain the selected person's name, not a reference to the Person object.
So in your example, you can make SelectedValue return the string by setting SelectedValuePath to "Content", which is the property of the ListBoxItem that contains the strings you're using.
You can do it another way by not explicitly creating ListBoxItems and just populating the ListBox with strings. You have to declare a namespace referencing mscorlib to do this, so that you can represent string objects in XAML, but once you do, the result's simple:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<DockPanel>
<ListBox DockPanel.Dock="Top" Margin="10" x:Name="test" SelectedValuePath="Length">
<sys:String>Log</sys:String>
<sys:String>DownloadRequest</sys:String>
<sys:String>EmailRequest</sys:String>
</ListBox>
<TextBlock DockPanel.Dock="Top" Margin="10" Text="{Binding ElementName=test, Path=SelectedItem}"/>
<TextBlock DockPanel.Dock="Top" Margin="10" Text="{Binding ElementName=test, Path=SelectedValue}"/>
</DockPanel>
</Page>
The Selected Value is a ListBoxItem, so you can cast the value to ListBoxItem, and then use the Content property:
ListBoxItem selItem = (ListBoxItem)dbTables.SelectedValue;
Console.WriteLine(selItem.Content);
String curItem = (dbTables.SelectedValue as ListBoxItem).Content.ToString();
I'm experiencing som strange behaviour by the Silverlight ComboBox. I started out with some simple code:
xaml:
<ComboBox Name="drpInstallation" SelectionChanged="drpInstallation_SelectionChanged" />
cs:
List<string> installations = new List<string>();
installations.Add("Testing 123");
installations.Add("Antoher test");
installations.Add("Yeah");
drpInstallation.ItemsSource = installations;
Everything works well when clicking an item. However, if I use the ItemTemplate in ComboBox like this:
xaml:
<ComboBox Name="drpInstallation" SelectionChanged="drpInstallation_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<ComboBoxItem Content="{Binding Installation}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
cs:
ICollection<InstallationClass> installations = a list of the installation class;
drpInstallation.ItemsSource = installations;
InstallationClass.cs:
public class InstallationClass
{
public int PK;
public string Installation;
}
Now the ComboBox displays correctly, however when I click the text if the items nothing happens. If I click just right of the text itself then the item is selected like normal. Point is; the natural thing to do is to click the text itself, not to the left or right of it. Any idea why this happens, and any idea how to correct it? Is this a Silverlight bug ?
Your DataTemplate should look like this:
<ComboBox Name="drpInstallation" SelectionChanged="drpInstallation_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Installation}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The problem was that ComboBoxItems consume the click event, rather than bubbling it up.