我遇到了以下问题:
我需要制作一个自定义的ContentControl,当没有聚焦时,会有一个带有TextBlock的默认DataTemplate,但是当聚焦(即鼠标或键盘)应该能够根据内容的类型呈现另一个合适的DataTemplate时。例如,让我们说如果Content的类型是String,那么应该显示带有TextBox的DataTemplate,如果它是DateTime - 然后是DateTimePicker,依此类推。
我知道有一种方法可以提供不同的DataTemplates,具体取决于ListBoxItems的Focused / NotFocused,我已经通过应用带触发器的Style实现了这一点。但在这种情况下,我被困住了。 我已经尝试过Style,但没有成功。
这是我到目前为止所提出的:
主题/ generix.xaml用于Gadget控件,它刚从ContentControl继承而来:
<ControlTemplate x:Key="String">
<Border BorderBrush="Green" BorderThickness="1">
<TextBlock Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}"></TextBlock>
</Border>
</ControlTemplate>
<ControlTemplate x:Key="Int32">
<Border BorderBrush="Blue" BorderThickness="1">
<TextBlock Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}"></TextBlock>
</Border>
</ControlTemplate>
<ControlTemplate x:Key="Base">
<Border BorderBrush="Yellow" BorderThickness="1">
<TextBlock Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}"></TextBlock>
</Border>
</ControlTemplate>
<local:DTC x:Key="DataTypeConverter"></local:DTC>
<Style TargetType="{x:Type local:Gadget}">
<Style.Triggers>
<DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:Gadget}}, Converter={StaticResource DataTypeConverter}}" Value="String}">
<Setter Property="Template" Value="{StaticResource String}"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:Gadget}}, Converter={StaticResource DataTypeConverter}}" Value="Int32}">
<Setter Property="Template" Value="{StaticResource Int32}"></Setter>
</DataTrigger>
</Style.Triggers>
<Setter Property="Padding"
Value="2" />
<Setter Property="Template" Value="{StaticResource Base}"> </Setter>
</Style>
Gadget控件后端只有一个静态构造函数:
static Gadget()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Gadget),
new FrameworkPropertyMetadata(typeof(Gadget)));
}
这是TestClass:
public class TestClass
{
public TestClass(string one, string two)
{
One = one;
Two = two;
Three = count++;
}
static int count = 0;
public string One { get; set; } = "One1";
public string Two { get; set; } = "Two2";
public int Three { get; set; }
}
这是valueConverter:
public class DTC : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
return value.GetType();
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}
这就是我尝试在ListBox中使用它的方法
<ListBox Name="lstBox" Margin="10,10,172,40">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<local:Gadget Content="{Binding Path=One}"></local:Gadget>
<local:Gadget Content="{Binding Path=Two}"></local:Gadget>
<local:Gadget Content="{Binding Path=Three}"></local:Gadget>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我到处搜索,但要么我不能很好地提出我的问题,要么也许根本没有人需要......
我真的很感激有关此事的任何建议!
提前多多感谢!
修改
为了使mm8工作的建议我编辑了DTC对象以返回Type而不是String。上面修剪的代码也是相应修复的。
答案 0 :(得分:0)
绑定到{RelativeSource Self}
的Content属性,并从转换器的Convert方法返回实际类型:
<Style TargetType="{x:Type local:Gadget}" xmlns:s="clr-namespace:System;assembly=mscorlib">
<Setter Property="Padding" Value="2" />
<Setter Property="Template" Value="{StaticResource Base}"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource Self}, Converter={StaticResource DataTypeConverter}}"
Value="{x:Type s:String}">
<Setter Property="Template" Value="{StaticResource String}"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource Self}, Converter={StaticResource DataTypeConverter}}"
Value="{x:Type s:Int32}">
<Setter Property="Template" Value="{StaticResource Int32}"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
public class DTC : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.GetType();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}