以下博客文章演示了如何动态显示不同的DataTemplate
,具体取决于ListBox
中显示的对象:
http://www.thejoyofcode.com/different_datatemplates_for_different_types.aspx
虽然这很有用,但我的具体情况更具挑战性。
我的主视图模型中有一组对象:
public IEnumerableCollection<IGenericObject> CurrentObjects
我目前使用XAML在ComboBox
中显示它们,如下所示:
<ComboBox ItemsSource="{Binding CurrentObjects}"
SelectedItem="{Binding SelectedObject,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged }"
DisplayMemberPath="Name"
SelectedIndex="0"/>
我现在希望在ComboBox
下面有一个单独的面板,它显示每个对象的属性。但是,每个对象具有不同的属性,具体取决于其具体类型。
例如,AObject
不仅支持IGenericObject
,还支持IAObject
,因此我希望始终显示所有对象共有的属性,然后动态显示所有对象的属性特定于当前选择的任何对象。
我不知道如何设置绑定并获取每个特定对象类型的属性值,因为我使用了常见的IGenericObject
接口。
我怎样才能做到这一点?
答案 0 :(得分:1)
显示每个对象的属性。
请记住,在流程结束时绑定只是反思。可以放置属性名称,如果绑定失败,则不显示任何内容。
但是,每个对象具有不同的属性,具体取决于其具体类型。
最终我们使用转换器来隐藏标签和文本块,具体取决于组合框中所选项目所包含的目标类型。
示例强>
此示例是与First
,Last
和Phone
共享相同属性的人员和员工,但员工与此人不同EmployeeId
。我们希望显示两者的名字和姓氏,但如果其员工也显示其ID。还要换掉标题,说明它是员工还是个人。
组合中的姓氏,两个对象,Smith
是一个人,Man
是一名员工。因此,当我们有一个人时,屏幕会显示:
当一名员工用最后信息的ID显示时:
<强>的Xaml 强>
<Page x:Class="WPFStack.Views.BindingCoverterPage"
...
xmlns:local="clr-namespace:WPFStack.Views"
xmlns:model="clr-namespace:WPFStack.Model"
xmlns:converter="clr-namespace:WPFStack.Converters"
.>
<Page.Resources>
<model:People x:Key="people">
<model:Person First="Joe"
Last="Smith"
Phone="303-555-5555" />
</model:People>
<model:Employees x:Key="employeePeople">
<model:Employee First="Omega"
Last="Man"
Phone="303-867-5309"
EmployeeId="90125" />
</model:Employees>
<converter:EmployeeVisiblity x:Key="isEmployeeVisibility"/>
<Style x:Key="LabelStyle" TargetType="Label" >
<Setter Property="Margin" Value="-20,0,0,0"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</Page.Resources>
<StackPanel Margin="10"
HorizontalAlignment="Left">
<ComboBox Name="mySelectionCombo"
SelectedItem="{Binding SelectedObject,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged }"
DisplayMemberPath="Last"
SelectedIndex="0"
Width="200">
<ComboBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource people}}" />
<CollectionContainer Collection="{Binding Source={StaticResource employeePeople}}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
<StackPanel Margin="10">
<Label Content="Employee Stats:"
Style="{StaticResource LabelStyle}"
Visibility="{Binding SelectedItem,
ElementName=mySelectionCombo,
Converter={StaticResource isEmployeeVisibility}}" />
<Label Content="Person Stats:"
Style="{StaticResource LabelStyle}"
Visibility="{Binding SelectedItem,
ElementName=mySelectionCombo,
ConverterParameter=Reverse,
Converter={StaticResource isEmployeeVisibility}}" />
<TextBlock Text="{Binding SelectedItem.First, ElementName=mySelectionCombo}" />
<TextBlock Text="{Binding SelectedItem.Last, ElementName=mySelectionCombo}" />
<TextBlock Text="{Binding SelectedItem.EmployeeId, ElementName=mySelectionCombo}"
Visibility="{Binding SelectedItem,
ElementName=mySelectionCombo,
Converter={StaticResource isEmployeeVisibility}}" />
</StackPanel>
</StackPanel>
</Page>
<强>转换器强>
namespace WPFStack.Converters
{
public class EmployeeVisiblity : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var isVisible = Visibility.Collapsed;
if (value != null)
if (value is Employee)
{
if (parameter == null) // Does not say string "Reverse"
isVisible = Visibility.Visible;
}
else // Value is a person
{
if (parameter != null) // Does say string "Reverse"
isVisible = Visibility.Visible;
}
return isVisible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
}
<强>用法强>
请注意,该示例主要执行的操作只是绑定到类似(但与数据不同的类型)它是进程,而不是需要的数据专注于来回答问题。
即使我使用复合集合通过ItemsSource
来保存诸如你的数据集,我最终(像你一样)有一个不同的实例对象的列表,就像你的数据。
...所以
关注这一点,看看转换器如何工作以确定哪些可见,哪些不依赖于组合框选择的内容。
以下步骤需要实施和理解,以使其在您的代码中运行:
WPFStack.Converters
,因此将其带入Xaml使我xmlns:converter="clr-namespace:WPFStack.Converters"
。<converter:EmployeeVisiblity x:Key="isEmployeeVisibility"/>
中指定它。您需要隐藏的屏幕上的任何视觉控件,其Visbility
属性将绑定到当前所选的组合项(您可能需要提供绑定的名称)以及调用转换器以确定它是否显示,例如此xaml代码:
<TextBlock Text="{Binding SelectedItem.EmployeeId, ElementName=mySelectionCombo}"
Visibility="{Binding SelectedItem,
ElementName=mySelectionCombo,
Converter={StaticResource isEmployeeVisibility}}" />
这是您需要从此回复中得到的内容。