DataTemplate in ControlTemplate does not update binding

I created a control with 3 PART_s, one PART_ changes depending on the type associated with it, however, the values ​​changed in the control do not update the binding, it seems to work like a OneWay binding.

The part of the code that I believe is important here:

<DataTemplate x:Key="BooleanDAView" DataType="{x:Type sys:Boolean}"> <CheckBox IsChecked="{Binding ., Mode=TwoWay}"/> </DataTemplate> <DataTemplate x:Key="DateTimeDAView" DataType="{x:Type sys:DateTime}"> <extToolkit:DateTimePicker Value="{Binding ., Mode=TwoWay}"/> </DataTemplate> <DataTemplate x:Key="Int32DAView" DataType="{x:Type sys:Int32}"> <extToolkit:IntegerUpDown Value="{Binding ., Mode=TwoWay}"/> </DataTemplate> <DataTemplate x:Key="StringDAView" DataType="{x:Type sys:String}"> <TextBox Text="{Binding ., Mode=TwoWay}"/> </DataTemplate> 

....

 <ContentControl x:Name="PART_Content" Grid.Row="0" Grid.Column="1" Margin="{TemplateBinding Padding}" VerticalAlignment="Center" VerticalContentAlignment="Center" Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" > <ContentControl.ContentTemplateSelector> <controls:TypeBasedDataTemplateSelector> <controls:TypeBasedDataTemplateSelector.Templates> <controls:TypedDictionary> <sys:String x:Key="{x:Type sys:Boolean}">BooleanDAView</sys:String> <sys:String x:Key="{x:Type sys:DateTime}">DateTimeDAView</sys:String> <sys:String x:Key="{x:Type sys:Int32}">Int32DAView</sys:String> <sys:String x:Key="{x:Type sys:String}">StringDAView</sys:String> </controls:TypedDictionary> </controls:TypeBasedDataTemplateSelector.Templates> </controls:TypeBasedDataTemplateSelector> </ContentControl.ContentTemplateSelector> </ContentControl> 

For the content, I also tried ... RelativeSource={RelativeSource AncestorType=local:DABaseControl} , but no change.

If the DataTemplate Binding uses "{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" , the template does not change after installation.

Or is there a better way to do this?

thank

0
c # wpf binding xaml
Nov 16 '11 at 13:50
source share
2 answers

I just ran into the same problem, I wanted to create a DataTemplate with DataType="{x:Type sys:Boolean} , which had only a check mark. But along the way there were a lot of warning signs that said it was not like that must be done.

First, a simple binding {Binding} will throw an exception "Two-way binding requires a path or xpath", which was the first warning sign. I changed the binding to {Binding .} , Which worked (although this MSDN article clearly states that they are equivalent). The fact that voodoo helped was the second warning sign. Then it is displayed correctly, and the checked state corresponds to a logical value, but when the checkbox was UpdateSourceTrigger=PropertyChanged (even with UpdateSourceTrigger=PropertyChanged ), he refused to update the binding source, regardless of what I tried. Using diagnostics:PresentationTraceSources.TraceLevel=High showed that it did not even try to snap back (third warning sign).

I went ahead and created a simple “box” for the bool value - a class with a single bool property named Value with an implementation of INotifyPropertyChanged . I changed the binding to {Binding Value} , and now everything worked, including two-way binding.

Conclusion: It seems that the binding cannot update the associated object, but only the properties of this object (therefore {Binding} throws an exception, but the more explicit {Binding .} Suppresses this exception, according to the HB answer ). In any case, the approach of creating a ViewModel and creating templates that target it seems to be more than just a design guide, but an actual technical requirement.

+5
Oct 26
source share

I never really worked with a ContentTemplateSelector , but if I had to be wary of guesswork, I would say that it is not responding to PropertyChanged events in your ContentControl.Content property or is incorrectly bound to your Content binding.

You can easily check if your binding is correct or not by deleting the ContentTemplateSelector and seeing if the data is displayed at all. If so, your binding is correct. If this is not the case, this is not the case and you need to fix it.

If the problem is a ContentTemplateSelector , I would suggest switching to a DataTrigger , which determines which ContentTemplate use based on the Content. This is what I usually do and uses a converter that just returns typeof(value)

  <Style TargetType="{x:Type ContentControl}"> <Setter Property="ContentTemplate" Value="{StaticResource StringDAView}" /> <Style.Triggers> <DataTrigger Binding="{Binding Converter={StaticResource ObjectToTypeConverter}" Value="{x:Type sys:Boolean"> <Setter Property="ContentTemplate" Value="{StaticResource BooleanDAView}" /> </DataTrigger> <DataTrigger Binding="{Binding Converter={StaticResource ObjectToTypeConverter}" Value="{x:Type DateTime"> <Setter Property="ContentTemplate" Value="{StaticResource DateTimeDAView}" /> </DataTrigger> <DataTrigger Binding="{Binding Converter={StaticResource ObjectToTypeConverter}" Value="{x:Type sys:Int32"> <Setter Property="ContentTemplate" Value="{StaticResource Int32DAView}" /> </DataTrigger> </Style.Triggers> </Style> 
0
Nov 16 '11 at 15:02
source share



All Articles