wpf debug error output System.WIndows.Data Error 25 - wpf

I have a custom styled Combobox which works fine. It is placed inside a usercontrol and bound to a data structure. I use DisplayMemberPath to show only one element in the Combobox TextBox. The ComboBox Style is taken from MSDN and used many times. So it's not displayed here.
<UserControl x:Class="wpf.projext1.MyComboBox"
x:Name="MyControl"
...
<ComboBox Style="{StaticResource ComboBoxStyle}"
Text="{Binding ElementName=MyControl, Path=Text}"
IsEditable="True"
IsTextSearchEnabled="False"
StaysOpenOnEdit="True"
ItemsSource="{Binding ElementName=MyControl, Path=MyItemsSource}"
DisplayMemberPath="Name"
</ComboBox
I get the following annoying error message populating the output window:
System.Windows.Data Error: 25 : Both 'ContentTemplate' and 'ContentTemplateSelector' are set; 'ContentTemplateSelector' will be ignored. ComboBoxItem:'ComboBoxItem' (Name='')
if i leave out the
DisplayMemberPath="Name"
... no debug output about error 25 is shown. But I definitely need DiplayMemberPath="Name"!
Do You have an idea to fix this ?

You canĀ“t set both DisplayMemberPath and ItemTemplate at the same time.
DisplayMemberPath is used to tell the ItemsControl which property to display when showing your objects. It makes no sense to set this field if you're already passing a custom ItemTemplate, since you can choose how to show the object within that ItemTemplate.
Since the default Combobox style from MSDN also sets an ItemTemplate, this is likely the cause of the error.

resolved: use the TextSearch attached property, no matter if TextSearch is enabled!
TextSearch.TextPath="Name"

Should note TextSearch.TextPath="Name" instead of DisplayMemberPath="Name".

Related

Why ItemTemplate will make items disappear for ListView?

I was solving Windows Phone 8.1 ListView wobbling problem and had code like below, however, once I add the ItemTemplate, the contents of the List cannot be seen, I'm wondering why and how to fix the problem.
<ListView
Grid.Row="1"
x:Name="ListViewEvents"
Loaded="OnListViewEventsLoaded"
ItemsSource="{Binding xx}"
ItemTemplateSelector="{StaticResource xx}"
ItemContainerStyle="{StaticResource xx}"
IsItemClickEnabled="True">
<ListView.ItemTemplate >
<DataTemplate >
<Grid Width="{Binding ActualWidth, ElementName=EventsListGrid}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Your Width binding is trying to read the ActualWidth property of an element in your XAML named EventsListGrid, but there's no such element in the sample code you've provided. As such, the binding engine is unable to set the Width property on your grid, most likely setting it to some unset/NaN value. At least I can confirm this when setting up a similar case as the one you provided and inspecting in Snoop the ListViewItem containers generated for each item in the test collection bound to the ListView. Perhaps you want to set the element name to ListViewEvents in this case or some other parent element not shown in the example?

Bind a ComboBox to two DataContexts

I have a ComboBox in my wpf application.
It's ItemsSource is binded to some table in my DataSet.
I need the text property to be binded to another's object property . I doesn't work because the ComboBox doesn't want to get two DataContexts. How can I solve this problem?
<StackPanel Width="Auto" Height="Auto" MinWidth="296" Orientation="Vertical" x:Name="MyStackPanel">
<ComboBox x:Name="MyComboBox" ItemsSource="{Binding}" Text={Binding Path=MyProperty} />
</StackPanel>
In the code behind :
MyComboBox.DataContext = MyDataSet.Tables[MyTable];
MyStackPanel.DataContext = MyObject;
I want the ComboBox to show items from one DataContext but to show the text from another DataContext. How can I do it?
Don't use DataContext. Set the Source property of your bindings in XAML or create the bindings in code and set the Source property there.
Why are you assigning something to the datacontext of the stackpanel? From the looks of it, its not used.
Your code should work if MyDataSet.Tables[MyTable] returns an enumeration and contains a property called MyProperty.
What do you mean when you say that the combobox "doesn't want to get two DataContexts"?
Look into the properties IsEditable and IsReadOnly of the combobox.
Something like
<ComboBox x:Name="MyComboBox" ItemsSource="{Binding}" Text={Binding ElementName=MyStackPanel Path=DataContext.MyProperty} />

WPF ListBox ListBoxItem Binding

I am going through the Sams book "Teach Yourself WPF in 24 Hours". At one point the authors show how you can bind a ListBox's selected-item value to a property. I get that, it's pretty straightforward. But when I try to create my own ListBox control with my own ListBoxItems, I can't seem to get it to work.
The ListBox that works uses a system collection as its ItemsSource property:
<ListBox x:Name="FontList"
DockPanel.Dock="Left"
ItemsSource="{x:Static Fonts.SystemFontFamilies}"
Width="160" />
The value selected from this ListBox is then used in a TextBlock as follows:
<TextBlock Text="Test"
FontFamily="{Binding ElementName=FontList, Path=SelectedItem}"
TextWrapping="Wrap"
Margin="0 0 0 4" />
Notice that the Path is set to SelectedItem.
Now, I wanted to set the FontSize using another ListBox that contains 3 different sizes. Here is what I did:
<ListBox x:Name="Size" >
<ListBoxItem>10</ListBoxItem>
<ListBoxItem>15</ListBoxItem>
<ListBoxItem>20</ListBoxItem>
</ListBox>
And then I added a binding to the Size attribute of the TextBox as follows:
<TextBlock Text="Test"
FontFamily="{Binding ElementName=FontList, Path=SelectedItem}"
Size="{Binding ElementName=Size, Path=SelectedItem}"
TextWrapping="Wrap"
Margin="0 0 0 4" />
The Size doesn't change when I run the program. So I tried to add the binding I was using for Size to the Text attribute--in order to see its value:
<TextBlock Text="{Binding ElementName=Size, Path=SelectedItem}""
FontFamily="{Binding ElementName=FontList, Path=SelectedItem}"
Size="{Binding ElementName=Size, Path=SelectedItem}"
TextWrapping="Wrap"
Margin="0 0 0 4" />
I see that it is changing as I click the Size ListBox, but I also see that the SelectedItem is displaying as this (when I click the 15 entry):
System.Windows.Controls.ListBoxItem:15
My questions:
1) What is the actual value being returned by the Path called SelectedItem? Is it "System.Windows.Controls.ListBoxItem:15" or is it "15"? If it's not 15, how can I specify a Path that returns just 15 and not System.Windows.Controls.ListBoxItem:15?
2)Why does the FontFamily SelectItem work? I realize that the FontList is coming from a System collection of font names, but it is unclear to me why the ListBox isn't returning a collection of ListBoxItems as text. If my ListBox's Path reference is returning a SelectedItem object of type ListBoxItem, then I would think I could use a Path of SelectedItem.Value or something like that--but it doesn't work and there is no Intellisense to help me.
I want to get THIS example working because it will help clear-up some misunderstandings I have. Please don't refactor the solution to get it to work some other way unless it's entirely impossible for me to have a Path reference that will give me just the numeric portion of my Size ListBoxItem that is selected.
What is the actual value being returned by the Path called SelectedItem?
It is System.Windows.Controls.ListBoxItem:15 (you can read this as "ListBoxItem with content set to 15"), that's why your binding does not work - it expects a numeric value, not ListBoxItem. You can specify Path as SelectedItem.Content to make this work. Also you can set SelectedValuePath of ListBox "Size" to "Content", and bind to SelectedValue property instead of SelectedItem.
Solution 1:
<TextBlock Size="{Binding ElementName=Size, Path=SelectedItem.Content}" />
Solution 2:
<ListBox x:Name="Size" SelectedValuePath="Content" />
<TextBlock Size="{Binding ElementName=Size, Path=SelectedValue}" />
Why does the FontFamily SelectItem work?
Because that ListBox contains a font collection, not a collection of ListBoxItems (they are still created to represent each item in a collection though). You can achieve the same behavior with font sizes if you define collection of font sizes in code and bind ListBox'es ItemsSource property to that collection or define contents of your ListBox as a collection of System.Double values directly in XAML:
<ListBox x:Name="Size"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:Double>10</system:Double>
<system:Double>15</system:Double>
<system:Double>20</system:Double>
</ListBox>
1) The actual value being returned by your SelectedItem binding is a ListBoxItem object. To get the value (15) from your binding you could use a converter or make your binding path a bit more explicit to get the listbox item's Content property value:
Size="{Binding ElementName=Size, Path=SelectedItem.Content}"
2) This is a covariant operation so the type of each list item is inferred from its source. The items generated by your font family items control (ListBox) are a result of the collection it's bound to. The Items property (populated via the ItemsSource dependency property) is an ItemCollection of generic objects which take on the type of their corresponding contextual objects.

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?

Combobox's SelectedValue (or SelectedItem) OneWay binding not working. Any ideas?

In the below window, the Existing Reports combo is bound to an observeablecollection of reportObjects. I have a reportObject property currentReport bound to the combo's SelectedValue property, OneWay. However, that's not working when bound in XAML.
SelectedValue="{Binding currentReport, Mode=OneWay}"
TwoWay binds fine, but I can't do it that way without writing an undo() method to the reportObject class. I'm binding the currentReport's properties to the various textboxes for editing. I want to bind OneWay so the source doesn't get changed. The currentReport's properties are all TwoWay bound to the corresponding textboxes so when I update the table in SQL [Save], it'll pull from that object, who's data is current.
<TextBox Text="{Binding currentReport.reportName, Mode=TwoWay}"
All of the properties bound from currentReport to the textboxes work fine as well. The only problem is the OneWay binding from the SelectedValue to the currentReport object. Does anyone have any ideas how to get this to work? I saw there was a bug, but the post I saw was 2009.
Sorry about the yellow. Not my idea. =)
EDIT: Added this XAML just in case.
<ComboBox ItemsSource="{Binding reportsCollection}" SelectionChanged="cboReports_SelectionChanged"
DisplayMemberPath="displayName"
SelectedValue="{Binding currentReport, Mode=TwoWay}"
x:Name="cboReports" Width="342" Height="40" VerticalAlignment="Center"/>
Forget about you need to change values - that is a separate problem - need to review your data design. Start with the UI problem question. If you want a user to be able to select an item from a combo box then it must have two way binding. Your first question is SelectedValue="{Binding currentReport, Mode=OneWay}" is failing why?

Resources