【问题标题】:WPF binding multiple UserControls to a listboxWPF 将多个用户控件绑定到列表框
【发布时间】:2013-10-17 21:19:54
【问题描述】:

我有多个用户控件,我想在 ListBox 上显示它们 假设我有一个员工抽象用户控件,并且我有 2 个或更多用户控件,而不是为每个员工使用像 AdministrativeEmployee 和 FactoryEmployee 这样的员工我有不同的数据,但 UserControl 在 ViewModel 上非常相似(相同的大小,几乎相同的字段)我有一个抽象的 EmployeeViewModel、AdministrativeEmployeeViewModel 和 FatoryEmployeeViewModel,在EmployeesView 上我有带有数据绑定的ListBox,在EmployeesViewModel 上我有一个ICollectionEmployees

EmployeesView.xaml:

xmlns:local="clr-namespace:Solution.Controls"

-

    <ListBox ItemsSource={Binding Employees}>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <ContentPresenter Content="{Binding}" Name="Presenter" />
                <DataTemplate.Triggers>
                    <DataTrigger  Value="{x:Type local:AdministrativeEmployeeView}">
                        <Setter TargetName="Presenter" Property="Content">
                            <Setter.Value>
                                <local:AdministrativeEmployeeView />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <DataTrigger Value="{x:Type local:FactoryEmployeeView}">
                        <Setter TargetName="Presenter" Property="Content">
                            <Setter.Value>
                                <local:FactoryEmployeeView/>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

EmployeesViewModel.cs:

public ICollection<EmployeeViewModel> Employees { get; set; }

但这显示了 ListBox 上的 System.ItemTemplate,而不是每种员工类型的 UserControls

【问题讨论】:

  • 这是错字吗? ItemsSource={Binding Employees}应该是ItemsSource="{Binding Employees}"。而且没有 Binding 的 DataTrigger 是没用的。
  • 您似乎在这里使用了一种非常迂回的方法。为什么不直接定义指定类型的 DataTemplates?这将使用分配的模板自动呈现每种类型。

标签: c# wpf inheritance user-controls listbox


【解决方案1】:

ListBox 资源中定义了两个DataTemplate:

<ListBox ItemsSource="{Binding Employees}">
    <ListBox.Resources>
        <DataTemplate DataType="{x:Type local:AdministrativeEmployee}">
            <local:AdministrativeEmployeeView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:FactoryEmployee}">
            <local:FactoryEmployeeView />
        </DataTemplate>
    </ListBox.Resources>            
</ListBox>

模型类:

public class Employee
{
    public string Name { get; set; }   
}

public class AdministrativeEmployee : Employee
{
}

public class FactoryEmployee : Employee
{
} 

样本数据:

List<Employee> _source = new List<Employee>();
_source.Add(new AdministrativeEmployee { Name = "A test1" });
_source.Add(new FactoryEmployee { Name = "F test1" });
_source.Add(new AdministrativeEmployee { Name = "A test2" });
_source.Add(new FactoryEmployee { Name = "F test2" });
Employees = _source;

AdministrativeEmployeeView:

<UserControl ...>
    <Grid>
        <TextBlock Text="{Binding Name}" Background="Red" />
    </Grid>
</UserControl>

FactoryEmployeeView:

<UserControl ...>
    <Grid>
        <TextBlock Text="{Binding Name}" Background="Green" />
    </Grid>
</UserControl>

结果:

【讨论】:

  • 它非常接近我的需要,无论如何,我必须更改几行 xlmns:viewModels="clr-namespace:Solution.ViewModels" 并将 DataTemplates 更改为:&lt;DataTemplate DataType="{x:Type viewModels:AdministrativeEmployeeViewModel}"&gt; &lt;local:AdministrativeEmployeeView /&gt; &lt;/DataTemplate&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 2011-10-16
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 2014-11-28
  • 2011-05-07
相关资源
最近更新 更多