Binding mode for item in listbox
When using a DataTemplate for a ListBox item, my app freezes and throws an exception in the Output Window. The details follow.
Edit Template:
<DataTemplate x:Key="EditOnlyTemplate">
<Border BorderBrush="Blue" Margin="3" Padding="3" BorderThickness="2" CornerRadius="5" Background="Beige">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<TextBox Width="300" FontSize="25" Foreground="Goldenrod" Text="{Binding XPath=/doc/dob/text, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged, diag:PresentationTraceSources.TraceLevel=High}" />
<TextBox Width="300" FontSize="25" Foreground="Blue" Text="{Binding XPath=/doc/dob/group, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Width="300" FontSize="25" Foreground="Green" Text="{Binding XPath=/doc/dob/filter, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Save" Click="btnSave_Click" Width="40" HorizontalAlignment="Left" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}"/>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
I am using the following code behind to handle a button click and switch my DataTemplate on my ListBox Item from one which simply displays the bound data (ie, "Details" template) to one where I can modify the bound data (ie, "Edit" Template).
private void btnEdit_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
//command contains the list item
ContentControl itm = (ContentControl)btn.CommandParameter;
itm.ContentTemplate = this.FindResource("EditTemplate") as DataTemplate;
}
The thing to note about my EditTemplate is the Binding Mode of the first TextBox - it is set to OneWayToSource. This is what causes the problem, upon my clicking the "Edit" button that swaps in this template. If I change the Mode to "TwoWay" (the default Mode for the TextBox), there is no issue. Also, if I use a copy of this template in another place on the page, placed in during design - not via code - and not in a ListBox item, but rather, in a ContentControl the OneWayToSource Mode works as expected.
The exception thrown in my broken scenario is the following:
System.Windows.Data Warning: 104 : BindingExpression (hash=48690759): At level 0 - for XmlElement.InnerText found accessor ReflectPropertyDescriptor(InnerText)
System.Windows.Data Warning: 100 : BindingExpression (hash=48690759): Replace item at level 0 with XmlElement (hash=21889970), using accessor ReflectPropertyDescriptor(InnerText)
System.Windows.Data Warning: 86 : BindingExpression (hash=48690759): Update - got raw value ''
System.Windows.Data Warning: 90 : BindingExpression (hash=48690759): Update - using final value ''
System.Wi
ndows.Data Warning: 98 : BindingExpression (hash=48690759): SetValue at level 0 to XmlElement (hash=21889970) using ReflectPropertyDescriptor(InnerText): ''
A first chance exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=/InnerText; DataItem='XmlDocument' (HashCode=33583636); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') InvalidOperationException:'System.InvalidOperationException: Dispatcher processing has been suspended, but messages are still being processed.
at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value)
at MS.Internal.Data.PropertyPathWorker.SetValue(Object item, Object value)
at MS.Internal.Data.ClrBindingWorker.UpdateValue(Object value)
at System.Windows.Data.BindingEx开发者_运维技巧pression.UpdateSource(Object value)'
I suspect the ListBox is somehow the cause, but cannot understand why, except for possible bug. I am using the .Net Framework 3.5 with all current updates, on Windows XP. Does anyone see anything obviously wrong with what I am attempting to do?
Ignoring the exception and helping you get past your current implementation you should be making use of a DataTemplateSelector
. Here is a sample which takes place on a ListBox
.
OneWayToSource tries to update your bind data which probably isn't possible. OneWay binding should work fine.
精彩评论