我在ContentControl中使用一个ContentControl。我有3种不同的DataTemplates,基于3种不同的object types。当我将ContentControl的ContentControl设置为上述类型的数据时,DataTemplateSelector交换到特定的DataTemplate和选择器,而且似乎回滚/重置旧模板中的值。为什么是这样?
编辑:,我发现这些值是重新审核的,因为我有一个附加的属性,称为Prop,而在它的OnPropertyChangedCallback中,它通知我在DataTemplates之间的交换时,它的值为null。您可以在下面的代码中看到附加属性。
有人能帮我找出DataTemplateSelector交换机制背后的情况吗?
下面是对代码的更深层次的解释:
public void Window1()
{
InitalizeComponents();
}
public void OnClick(object sender, RoutedEventArgs e)
{
if(this.DataContext == null)
this.DataContext = "Hallo";
else{
if(this.DataContext is string)
this.DataContext = 123;
else{
if(this.DataContext is int)
this.DataContext = null;
}
}
}
By clicking on Button few times I change the type and so in ContentControl the selector changes to DataTemplate.选择器如下所示。它在textDataTemplate和numericDataTemplate之间交换,还有一个模板。正如我提到的,我有三种类型,string,int,and one more,我不想吃。他们的DataTemplates叫做textDataTemplate,numericDataTemplate,还有那个。:)
<local:MyTemplateSelector x:Key="dataTemplateSelector"
TextTemplate="{StaticResource textDataTemplate}"
NumericTemplate="{StaticResource numericDataTemplate}"/>
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate TextTemplate;
public DataTemplate NumericTemplate;
public DataTemplate Select(object item, Culture.....)
{
if(item is string)
{
return this.TextTemplate;
}
else
{
return this.NumericTemplate;
}
}
}ContentControl和XAML如下所示:
<Button Click="OnClick" Content="Click Me"/>
<ContentControl Name="contentCtrl"
Content="{Binding}"
Width="123"
ContentTemplateSelector="{StaticResource dataTemplateSelector}" />这就是textDataTemplate的相貌。
<DataTemplate x:Key="textDataTemplate">
<TextBox x:Name="text" my:AttProperties.Prop="{extension:MarkupExt value}" Text="{Binding Path=Txt, Mode=Default, UpdateSourceTrigger=Explicit}"/>
</DataTemplate>numericDataTemplate看起来类似于textDataTemplate,只是只允许数字。
Prop是我来自AttProperties class of type string的attached property。Prop就在这三个DataTemplate的某个地方。在Prop上面的是一个TextBox,但它也可能是一个Label。markupextension只是一个“返回Hello"。这个扩展只是为了测试如何创建一个自定义的标记扩展。延期没什么大不了的。它不应该与DataTemplates的交换有很大关系。
再解释一次我的问题。交换似乎是重置/回滚我的旧模板。我从textDataTemplate交换到numericDataTemplate,并且textDataTemplate的支持被设置为null,但是之前的值是"Hello“。
为什么会发生这种事?使用tiggers似乎也有相同的行为。一旦一个Trigger不再有效,它就回滚使用的值。DataTemplateSelector是否使用与Triggers相同的机制?
编辑的:附加的属性只是一个带有OnPropertyChangedCallback的简单.RegisterAttached。在OnPropertyChangedCallback内部,我认为当交换dataTemplates时,道具是空的。
发布于 2013-03-28 19:32:17
如果您在数字模板中使用双向绑定,并且它只接受类似Double的内容,则可以将值设置为number。但是没有人能确定没有看到完整的代码。有可能你自己的代码做错了什么。为了更好地理解事物,创建来自ContentControl的自己的控件,并在示例中使用它。然后重写控制方法OnContentxxxChanged,在那里插入断点并调试应用程序。你应该明白,你的数据和模板选择器是怎么回事。当应用程序在断点上停止时,请仔细检查所有值并查看堆栈跟踪。要调试绑定,可以插入IValueConverters,这将为您在代码中提供位置,您可以在其中检查值。
我真的建议你先做最简单的工作,然后再去做一些更复杂的事情,比如有双向绑定的文本框,以及一些你在问题中没有显示的控件属性。下面是TextBlocks的工作版本:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void OnClick(object sender, RoutedEventArgs e)
{
if (this.DataContext == null)
this.DataContext = "Hallo";
else if (this.DataContext is string)
this.DataContext = 123;
else if (this.DataContext is int)
this.DataContext = null;
}
}
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate TextTemplate {get; set;}
public DataTemplate NumericTemplate {get; set;}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is string)
{
return this.TextTemplate;
}
else
{
return this.NumericTemplate;
}
}
}和xaml:
<Grid>
<Grid.Resources>
<DataTemplate x:Key="numericDataTemplate">
<TextBlock Foreground="Red" Text="{Binding}" />
</DataTemplate>
<DataTemplate x:Key="textDataTemplate">
<TextBlock Foreground="Green" Text="{Binding}"/>
</DataTemplate>
<local:MyTemplateSelector x:Key="dataTemplateSelector"
TextTemplate="{StaticResource textDataTemplate}"
NumericTemplate="{StaticResource numericDataTemplate}"/>
</Grid.Resources>
<StackPanel>
<Button Click="OnClick" Content="Click Me" VerticalAlignment="Top"/>
<ContentControl Name="contentCtrl"
Content="{Binding}"
Width="300" Height="100"
ContentTemplateSelector="{StaticResource dataTemplateSelector}" />
</StackPanel>
</Grid>和你的代码比较。当您从DataTemplateSelector继承时,您应该重写SelectTemplate方法,而不是发明其他名称的方法。所有控件(如ContentControl )都将只使用SelectTemplate。等等。
显然,所有的工作和DataTemplateSelector没有做错什么。我想,你的问题就在你的数据和绑定中。
查看您的OnClick方法-它总是将DataContext设置为null。
https://stackoverflow.com/questions/15544366
复制相似问题