在usercontrol中为listbox设置itemtemplate

时间:2016-11-04 15:28:55

标签: c# wpf xaml user-controls

我在UserControl中有一个Listbox来管理具有不同属性的不同实体。 UserControl对于所有实体都是相同的。 我使用MVVM,并将通用ViewModel绑定为UserControl的DataContext。 我希望在容器xaml中为UserControl设置Listbox的ItemTemplate,以显示实体属性。 对于实体" Emlployee"我需要显示FullName,对于实体认证我需要显示CertifyingAuthor和CertifyingDate等。

我需要的是类似的东西

// Code goes here

var trIdP = 0;

function add() {
  var typeP = document.getElementById("typeP").value;
  var valueP = document.getElementById("valueP").value;
  var newText = document.createTextNode(typeP);
  var newText2 = document.createTextNode(valueP + " Eur");
  var newText3 = document.createTextNode("button");
  var tablePr = document.getElementById("tableP").getElementsByTagName('tbody')[0];
  if ((typeP !== "") && (valueP !== "")) {
    var newRow = tablePr.insertRow(-1);
    newRow.id = "trP" + trIdP;
    var newCell1 = newRow.insertCell(0);
    var newCell2 = newRow.insertCell(1);
    var newCell3 = newRow.insertCell(2);

    newCell1.appendChild(newText);
    newCell2.appendChild(newText2);
    newCell3.innerHTML = "<a onclick=\"deleteRow(" + trIdP + ")\"><div>Row: " + trIdP + "</div></a>";

    document.getElementById("typeP").value = "";
    document.getElementById("valueP").value = "";

    trIdP++;
  }
}

function deleteRow(id) {
  document.getElementById("trP" + id).remove();
}

我应该将dependencyProperty ItemTemplateForTheInsideListBoxProperty添加到UserControl吗?我怎么能把它作为Listbox的itemtemplate传递?

希望考虑到我的意大利语母语,可以很好地解释这个问题。 感谢

编辑:我放弃了。这是键盘数据输入的控件,类似于自动完成。 因为我被迫同意与MVVM妥协:(我将选择一些肮脏的方式来解决。 感谢所有

1 个答案:

答案 0 :(得分:0)

DataTemplateSelector可以做我想你想要的。您可以从用户控件的XAML定义不同的模板,然后让选择器从中选择。

假设这些模型类:

public class Employee
{
    public Employee(string fullName)
    {
        FullName = fullName;
    }

    public string FullName { get; }
}

public class Certifying
{
    public Certifying(string certifyingAuthor, DateTime certifyingDate)
    {
        CertifyingAuthor = certifyingAuthor;
        CertifyingDate = certifyingDate;
    }

    public string CertifyingAuthor { get; }

    public DateTime CertifyingDate { get; }
}

您的用户控件的XAML有ListBox,后者又使用模板选择器(我们稍后会介绍) - 并且还为两种不同的模型类型定义了不同的模板:

<UserControl
    x:Class="WPF.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPF"
    >
    <Grid>
        <ListBox x:Name="listBox">
            <ListBox.ItemTemplateSelector>
                <local:MyTemplateSelector>
                    <local:MyTemplateSelector.EmployeeTemplate>
                        <DataTemplate DataType="local:Employee">
                            <TextBlock
                                Foreground="Red"
                                Text="{Binding FullName}"
                            />
                        </DataTemplate>
                    </local:MyTemplateSelector.EmployeeTemplate>
                    <local:MyTemplateSelector.CertifyingTemplate>
                        <DataTemplate DataType="local:Certifying">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="120" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <TextBlock
                                    Foreground="Blue"
                                    Text="{Binding CertifyingAuthor}"
                                />
                                <TextBlock
                                    Grid.Column="1"
                                    Foreground="Green"
                                    Text="{Binding CertifyingDate}"
                                />
                            </Grid>
                        </DataTemplate>
                    </local:MyTemplateSelector.CertifyingTemplate>
                </local:MyTemplateSelector>
            </ListBox.ItemTemplateSelector>
        </ListBox>
    </Grid>
</UserControl>

用户控件的代码隐藏,我只是将模型对象列表分配给列表框(为简单起见):

public partial class UserControl1
{
    public UserControl1()
    {
        InitializeComponent();
        listBox.ItemsSource = new List<object>
            {
                new Employee("Donald Duck"),
                new Certifying("Mickey Mouse", DateTime.Now),
                new Employee("Napoleon Bonaparte"),
                new Certifying("Homer Simpson", DateTime.Now - TimeSpan.FromDays(2)),
            };
    }
}

最后,模板选择器。它的两个属性是从用户控件的XAML设置的; SelectTemplate的逻辑决定应用哪一个:

public class MyTemplateSelector : DataTemplateSelector
{
    /// <summary>
    /// This property is set from XAML.
    /// </summary>
    public DataTemplate EmployeeTemplate { get; set; }

    /// <summary>
    /// This property is set from XAML.
    /// </summary>
    public DataTemplate CertifyingTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is Employee)
        {
            return EmployeeTemplate;
        }

        if (item is Certifying)
        {
            return CertifyingTemplate;
        }

        return base.SelectTemplate(item, container);
    }
}

并且,为了完整性,使用用户控件:

<Grid>
    <wpf:UserControl1 />
</Grid>

最终结果,拿破仑目前被选中,荷马遭遇鼠标悬停:

enter image description here