I recently upgraded my Silverlight app from 3 to 4. After a few hours of bashing my head against the wall, trying to resolve an issue, I've narrowed down the problem to this:
I have a user control, with a ComboBox inside it. The ComboBox has a single ComboBoxItem child. The user control exposes a get accessors that returns the ComboBox's Items object, allowing me to add additional ComboBoxItems via xaml.
This all worked fine in Silverlight 3, however it's not working in Silverlight 4.
As code:
//XAML
<UserControl ... >
<ComboBox Name="myComboBox">
<ComboBoxItem Content="Select an Item" />
</ComboBox>
<!-- All my other stuff -->
</UserControl>
//Code behind
public ItemCollection ListItems
{
get
{
return myComboBox.Items;
}
}
//Implementation of User-Control
<CustomControl:UserControl ... >
<CustomControl:UserControl.ListItems>
<ComboBoxItem Content="Item 1" />
<ComboBoxItem Content="Item 2" />
<ComboBoxItem Content="Item 3" />
</CustomControl:UserControl.ListItems>
</CustomControl:UserControl>
As I mentioned, this all worked fine in Silverlight 3, but doesn't work in Silverlight 4.
The workaround, it seems, is to remove that single ComboBoxItem that's inside my user-control, but I'm hoping to avoid, as I want it as the default item.
Any help would be much appreciated!
The XAML parser was re-written for Silverlight 4 to make it more consistent with WPF. I am pretty certain the behavior you are expecting was a bug in SL3 and I don't think it would have worked that way in WPF though I've never actually tried.
You may be able to get the old mode back by enabling quirks mode but I wouldn't recommend it. Instead, what I would do is create a ControlTemplate for the combo box to display the "select an item" text when there is nothing selected. Having that be an actual item in the combo box really just a hack that we've always been forced to do with technologies such as Windows Forms and HTML but in Silverlight it seems like having SelectedItem be null is more appropriate.
Related
I try to use a CheckComboBox control from the Xceed library.
When I select an item, the control displays system.windows.controls.comboxitem:"value" instead of just value
Is there a way to display only the value of the selected item without its type?
<xctk:CheckComboBox>
<ComboBoxItem Content="SA" />
<ComboBoxItem Content="NA" />
</xctk:CheckComboBox>
In this particular case it can be solved by adding the DisplayMemberPath="Content"
<xctk:CheckComboBox DisplayMemberPath="Content">
<ComboBoxItem Content="SA"/>
<ComboBoxItem Content="NA"/>
</xctk:CheckComboBox>
But whether it is a designed feature or just a serendipitous behaviour, I am not sure.
So overall it would be better in the future to read on WPF binding, and use datasources and bindings to make the code similar to what is on the documentation page.
<xctk:CheckComboBox
DisplayMemberPath="Color"
ValueMemberPath="Level"
SelectedValue="{Binding SelectedValue}"
SelectedItems="{Binding SelectedItems}" />
I have a combobox in a WPF XAML window. I want to have an IF statement in my .cs where I can then assign a method to it when the user has that item selected.
Here is the XAML bit:
<ComboBox x:Name="comboBoxThickness" HorizontalAlignment="Left"
Margin="469,380,0,0" VerticalAlignment="Top" Width="155" IsEditable="True"
MaxWidth="150" Text="Select Plate Thickness">
<ComboBoxItem x:Name="Combo8mm" Content="8mm" />
<ComboBoxItem x:Name="Combo12_5mm" Content="12.5mm" />
</ComboBox>
Here is the .cs part (with an attempt made):
private void WeightCal()
{
if (Combo8mm.Selected){
}
}
Based on your question, I have added code snippet assuming that you wanted to do something on combo-box selected changed event.
Case 1 :-
I have done little modification to your xaml and code-behind.
Added a SelectedChanged event to combobox as below.
<ComboBox x:Name="comboBoxThickness" HorizontalAlignment="Left" VerticalAlignment="Top" Width="155" IsEditable="True"
MaxWidth="150" Text="Select Plate Thickness" SelectionChanged="comboBoxThickness_SelectionChanged">
<ComboBoxItem x:Name="Combo8mm" Content="8mm" />
<ComboBoxItem x:Name="Combo12_5mm" Content="12.5mm" />
</ComboBox>
Then in the code behind in the event handler, you can check which Combobox item is selected like below,
private void comboBoxThickness_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedItem = comboBoxThickness.SelectedItem as ComboBoxItem;
if(selectedItem.Content.ToString() == "8mm")
{
// Write your logic here
}
}
You can multiple if..else conditions to check and do necessary actions in each if condition as per your requirements.
Note:- Even though the approach you have followed was not recommended. Always rely on MVVM which helps you in long run.
And in the above code I am just trying to compare the selected combo-box item content with string. Assuming it is always a string in your case. You have to check and test the code in your project.
Case 2:-
In case if you want to get the selected item in some method, you can directly use this below statement instead of checking that each combo-box item is selected or not which you have written in your code.
var selectedItem = comboBoxThickness.SelectedItem as ComboBoxItem;
if(selectedItem.Content.ToString() == "8mm")
{
// Write your logic here
}
If there is something else that you are looking for, then let us know.
hope you can help me, there are a lot of posts on this topic, but none matches my problem really.
I've got a WPF-Window with unbound text- and comboboxes. They're filled in a foreach-loop on load programmatically by c# code with values from an Xml-database.
switch (TypeOfSync)
{
case SyncType.FromXmlDataBase:
MyControl.Text = MyXmlSubNode.InnerText;
break;
case SyncType.ToXmlDataBase:
MyXmlSubNode.InnerText = MyControl.Text;
break;
default:
break;
}
The target combobox may not be editable.
<ComboBox x:Name="OPReason">
<ComboBoxItem Content=""/>
<ComboBoxItem Content="Erstimplantation"/>
<ComboBoxItem Content="Revision bis 3 Monate"/>
<ComboBoxItem Content="Revision"/>
</ComboBox>
In all other comboboxes everything works well. Also in this box everything is ok, until the the code sets the text property to "Revision". Then nothing is displayed, even if return value of the text property shows the correct value.
Of course you will say now, choose a databinding approach, but other actions have to performed simultaneously, so this is not really an option. A bit misterious. Might the similar beginning of "Revision" and "Revision bis 3 Monate" be the problem??
Filling text- and comboboxes manually by code from an XmlDatabases seems to be an susceptible way. Using databindings with a viewmodel is much safer and more reliable.
I have a very strange problem with WPF ComboBoxes:
I have the following XAML:
<ComboBox x:Name="cbSyncPriority">
<ComboBoxItem Content="Initial" />
<ComboBoxItem Content="Low"/>
<ComboBoxItem Content="Medium" />
<ComboBoxItem Content="High" />
</ComboBox>
<Button x:Name="btnSyncSynchronize" Content="Synchronize" Click="btnSyncSynchronize_Click"/>
and the following Code Behind:
private void btnSyncSynchronize_Click(object sender, RoutedEventArgs e)
{
string priority = cbSyncPriority.SelectedItem as string;
_synchronizationController.Synchronize(priority);
}
Now I have 2 projects with exact the same XAML and Code Behind files. But for some reason the behaviors differs:
Project 1:
The value of cbSyncPriority.SelectedItem is a String (equals to the Content value of the selected ComboBoxItem object)
Project 2:
The value of cbSyncPriority.SelectedItem is a ComboBoxItem (equals to the selected ComboBoxItem object).
Some background information why I have duplicate projects:
Using TFS I am working with two branches:
Main Development Branch
Sub Development Branch
The 'Sub Development Branch' is a copy from the 'Main Development Branch' so the code suppose to be the same.
How is it possible exact the same code have different behaviours?
I have a listbox in Wpf. I directly add items to this listbox. I added a clear button which runs the items.clear() command and it deletes all the items. However when restarting the app, all the items are back in the list! Are they stored somewhere and if so, how can I disable this?
Another question: Can a datatemplate be applied to a listbox in which items are directly added and not bound?
Code example:
<ListBox x:Name="Results" Margin="222,31,8,44" />
Midiinput.ChannelMessageReceived += delegate(object sender, ChannelMessageEventArgs e)
{
string result = e.Message.MessageType.ToString() + " " + e.Message.Command.ToString() + " " + e.Message.Data1.ToString() + " " + e.Message.Data2.ToString();
Results.Items.Add(result); Clearbutton.IsEnabled = true;
};
the listbox items is not persisted (as any other property in fact).
How do you populate your listbox ? is there any backend storage ?
I guess that your application simply have some items declared in the markup and when the application starts, the list items are parsed.
If the items return when you restart your app, I would think one of the following is true:
1) You are populating the listbox at DESIGN time by using the Items property and entering strings into the collection by hand.
2) You are running code that is populating the list from a storage location, either in the code or in a file.
-C
For your second question
Can a datatemplate be applied to a
listbox in which items are directly
added and not bound?
The ItemTemplate of a ListBox is copied to the ContentTemplate of a ListBoxItem during UI generation. However, when adding the ListBoxItems directly, ItemTemplate is ignored for items already of the ItemsControl's container type (ListBoxItem). So you'll have to use the ContentTemplate of ListBoxItem instead. Here's an example
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Foreground="Green" Text="{Binding}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem Content="Item 1"/>
<ListBoxItem Content="Item 2"/>
<ListBoxItem Content="Item 3"/>
</ListBox>
For your problem with items that are re-appearing when re-starting your app:
I'd try to find all the places where you add items to your ListBox in code-behind (search for Results.Items.Add). Add a breakpoint to each of those places to see in the debugger when you're adding them. The ListBox itself won't have any memory of how it looked when it closed unless you implement this.
If this doesn't work, try to change the name of your ListBox to ResultsTest or something, compile and fix all the errors you get by commenting out all the code that is referencing the ListBox and run the program again. This should leave you with no items in the ListBox. After this, start to uncomment your code, step by step until you find the place of the error.