我正在使用以下课程:
public class ConcreteClassFoo
{
public ObservableCollection<ConcreteComponent> Components { get; set; }
}
public class ConcreteComponent
{
IAttribute Foo { get; set; }
}
public class ConcreteAttribute1 : IAttribute {}
public class ConcreteAttribute2 : IAttribute {}
映射在我的XAML中:
<ListView ItemsSource={Bindings Components} />
如您所见,我的ListBox
将Components
属性绑定为ItemsSource
。
Components
属性是抽象类型ConcreteComponent
的 HAS-A 属性Foo
的{{1}}集合。
我想根据属性IAttribute
的具体类更改ListView
模板。
使用Foo
,可以根据类具体类型构建不同的模板,例如:
DataTemplate
但是如何根据具体类属性类型构建不同的模板呢?
更新:
我为实际问题增加了一些信息。
我的<DataTemplate DataType="{x:Type ConcreteComponent1}" />
<DataTemplate DataType="{x:Type ConcreteComponent2}" />
包含名为ListView
的{{1}}。对象ObservableCollection<BaseWindowShape>
的属性Shapes
(BaseWindowShape
是抽象的)可以是AdditionalData
或AdditionalData
。
我希望根据DistanceAdditionalData
具体类型更改che TermoAdditionalData
视图(ListView
中的所有AdditionalData
共享相同的具体{{1} }})。
因此,如果第一个形状的BaseWindowShape
为ListView
,我希望有三列
否则,我希望只有两列
AdditionalData
和AdditionalData
属于DistanceAtdditionalData
个属性,而MaxDistance
属于MinAreaPercent
属性。
我尝试以下列方式实现此行为,但它不起作用。
我怎么能解决我的问题?
DistanceAdditionalData
更新2 : 我使用 lokusking 回答来更新我的实现,这里是:
MaxTemperature
我添加了一个名为TermoAdditionalData
的属性,声明为:
<ListView ItemsSource="{Binding Shapes}">
<ListView.Resources>
<DataTemplate DataType="{x:Type additionalData:TridimensionalAdditionalData}">
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Header="Level">
<GridViewColumn.CellTemplate>
<DataTemplate>
<wpfControls:DigitInput Value="{Binding Level, Mode=TwoWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Max Distance">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<xctk:DoubleUpDown Value="{Binding MaxDistance}"/>
<TextBlock Text="mm">
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Min Area">
<GridViewColumn.CellTemplate>
<DataTemplate>
<xctk:DoubleUpDown Value="{Binding MinAreaPercent}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
<DataTemplate DataType="{x:Type additionalData:ThermalAdditionalData}">
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Header="Level">
<GridViewColumn.CellTemplate>
<DataTemplate>
<wpfControls:DigitInput Value="{Binding Level, Mode=TwoWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Max Temperature">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<xctk:DoubleUpDown Value="{Binding MaxTemperature}"/>
<TextBlock Text=" °F"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding AdditionalData}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
并将其绑定为我的第一个<ListView ItemsSource="{Binding FirstComponent}">
<ListView.Resources>
<DataTemplate DataType="{x:Type local:ConcreteAttribute1}">
<ListView ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Components}">
<ListView.View>
<GridView>
<GridViewColumn Header="1 column">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Foo.Name, Mode=OneWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="2 column">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Foo.Number, Mode=OneWay}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ConcreteAttribute2}">
<ListView ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Components}">
<ListView.View>
<GridView>
<GridViewColumn Header="3 column">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Foo.Name, Mode=OneWay}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="4 column">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Foo.B, Mode=OneWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Foo}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
的{{1}}。
正如FirstComponent
public ObservableCollection<ConcreteComponent> FirstComponent { get; } = new ObservableCollection<ConcreteComponent> { Components.First() };
我宣布了另一个ItemsSource
,绑定到集合ListView
,以便具有不同的列,具体取决于它。
如果我的集合的第一个元素的属性为DataTemplate
,我会得到以下结果:
否则以下一个:
可能这不是实现此结果的最佳方式(我必须声明只有一个元素的FirstComponent
才能检查它)但是它可以工作。
答案 0 :(得分:2)
因为我真的没有得到你想要达到的目标,我只能猜测,这就是你想要做的事情:
<ListView ItemsSource="{Binding Components}">
<ListView.Resources>
<DataTemplate DataType="{x:Type ConcreteAttribute1}">
<TextBlock Text="Con1"></TextBlock>
</DataTemplate>
<DataTemplate DataType="{x:Type ConcreteAttribute2}">
<TextBlock Text="Con2"></TextBlock>
</DataTemplate>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Foo}"></ContentControl>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
如果这不能解决您的问题,请再解释一下
修改强>
这里是我的演示实现和结果:
<强>类强>
public class ConcreteComponent {
public IAttribute Foo {
get; set;
}
}
public class ConcreteAttribute1 : IAttribute {
public string Name => "ConAtt 1";
public int Number => 999;
}
public class ConcreteAttribute2 : IAttribute {
public string Name => "ConAtt 2";
public bool B => true;
}
public interface IAttribute {
string Name {
get;
}
}
<强> XAML 强>
<ListView ItemsSource="{Binding Components}">
<ListView.Resources>
<DataTemplate DataType="{x:Type ConcreteAttribute1}">
<StackPanel>
<TextBlock Text="{Binding Name, Mode=OneWay}"/>
<TextBox Text="{Binding Number, Mode=OneWay}"></TextBox>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type ConcreteAttribute2}">
<StackPanel>
<TextBlock Text="{Binding Name, Mode=OneWay}"/>
<CheckBox IsChecked="{Binding B, Mode=OneWay}"></CheckBox>
</StackPanel>
</DataTemplate>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Foo}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<强>用法强>
public MainWindow() {
InitializeComponent();
this.Components = new ObservableCollection<ConcreteComponent>();
this.Components.Add(new ConcreteComponent { Foo = new ConcreteAttribute1() });
this.Components.Add(new ConcreteComponent { Foo = new ConcreteAttribute2() });
this.DataContext = this;
}
public ObservableCollection<ConcreteComponent> Components {
get;
}
<强>结果强>
注意强>
确保你没有错别字。 如果它仍然不起作用,可能会发布错误输出和/或异常的屏幕