无法绑定到ListBox

时间:2016-04-21 13:51:58

标签: c# wpf xaml listbox

我绑定到ListBox,并在ListBox中绑定另一个ListBox。

我的模型看起来像

public interface ICriteriaDetail
{
    string Title { get; }
    int NumberOfEvents { get; }
    ICriteriaDetail ChildCriteria { get; }
}

所以,我正在为孩子使用递归方法(不是列表)。

当我绑定到ListView时,我将列表中的项目,一个在另一个下面。

问题是,子项目根本没有显示!

虚拟数据

  public static IEnumerable<ICriteriaDetail> GetCriteriaList()
    {
        var list = new List<CompoundCriteria.Ui.Model.Interfaces.ICriteriaDetail>();
        list.Add(GetCriteriaDetail("My Title", 5, false));
        list.Add(GetCriteriaDetail("Other", 3, false));
        list.Add(GetCriteriaDetail("Biggy", 8, true));

        var child = new CompoundCriteria.Ui.Model.CriteriaDetail.CriteriaDetail("childAgain", 43, null);
        var child2 = new CompoundCriteria.Ui.Model.CriteriaDetail.CriteriaDetail("childAgainAgain", 13, child);

        list.Add(new CompoundCriteria.Ui.Model.CriteriaDetail.CriteriaDetail("Really big", 86, new CompoundCriteria.Ui.Model.CriteriaDetail.CriteriaDetail("smaller", 15, child2)));

        return list;
    }

    private static ICriteriaDetail GetCriteriaDetail(string title, int events, bool hasChild)
    {
        if (!hasChild)
            return new CompoundCriteria.Ui.Model.CriteriaDetail.CriteriaDetail(title, events, null);

        var child = new CompoundCriteria.Ui.Model.CriteriaDetail.CriteriaDetail("child" + title, 13 + events, null);
        return new CompoundCriteria.Ui.Model.CriteriaDetail.CriteriaDetail(title, events, child);
    }

ViewModel

    public MainWindowViewModel()
    {
        this.Criterias = DatasourceMockup.GetCriteriaList();
    }

    private IEnumerable<ICriteriaDetail> _criterias;
    public IEnumerable<ICriteriaDetail> Criterias
    {
        get { return _criterias; }
        set { _criterias = value; }
    }

XAML中的ListBox

 <ListBox ItemsSource="{Binding Criterias}" >
                    <ListBox.Resources>
                         <ControlTemplate x:Key="con">
                            <StackPanel Orientation="Horizontal">
                            <StackPanel Margin="15">
                                <TextBlock Text="{Binding Title}" />
                                <TextBlock Text="Events: ">
                                <Run Text="{Binding NumberOfEvents}" />
                                </TextBlock>
                             </StackPanel>
                             <ListBox ItemsSource="{Binding ChildCriteria} Visibility="{Binding ChildCriteria, Converter={StaticResource HideIfNull}}">">
                                    <ListBox.Resources>
                                        <DataTemplate DataType="{x:Type cDetail:CriteriaDetail}">
                                                <TextBlock Text="{Binding Title}" />
                                        </DataTemplate>
                                    </ListBox.Resources>
                                </ListBox>
                            </StackPanel>
                        </ControlTemplate>

                        <HierarchicalDataTemplate DataType="{x:Type cDetail:CriteriaDetail}">
                                <Control Template="{StaticResource con}" />
                        </HierarchicalDataTemplate>
                    </ListBox.Resources>
                </ListBox>

看完TreeView, HierarchicalDataTemplate and recursive Data之后,似乎HierarchicalDataTemplate就足够了(也不需要DataTemplate)但是,我很遗憾为什么我没有看到我预期的结果(即使孩子们不在理想的地方,我仍然希望看到他们)

修改

我刚刚添加了一个转换器,如果绑定数据为null,则会使ListBox(ControlTemplate中的一个)隐藏。我有一个轮廓(一个空的ListBox)只有3中的一个(这是正确的)但它不绑定任何内容(标题)。输出窗口显示没有任何用处...

请注意,儿童没有限制。在上面的示例中,存在父子关系,但它可以是父子孩子等等

1 个答案:

答案 0 :(得分:1)

1)很难理解你的目的,为什么ListBox,如果你在模型中有ChildCriteria,而不是IEnumerable<ICriteriaDetail>

2)你也有绑定错误,我将xaml更改为

<ListBox ItemsSource="{Binding Criterias}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <StackPanel Margin="15">
                            <TextBlock Text="{Binding Title}" />
                            <TextBlock Text="Events: ">
                                <Run Text="{Binding NumberOfEvents}" />
                            </TextBlock>
                </StackPanel>
                <TextBox Text="{Binding Path=DataContext.ChildCriteria.Title, 
                                        RelativeSource={RelativeSource Mode=FindAncestor, 
                                                        AncestorType={x:Type ListBoxItem}, 
                                                        AncestorLevel=1}}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

得到了

My result

EDIT1: 1)我将数据模型更改为

public class CriteriaDetail : ICriteriaDetail
{
    public CriteriaDetail(string title, int numberOfEvents, IEnumerable<ICriteriaDetail> childCriteria)
    {
        Title = title;
        NumberOfEvents = numberOfEvents;
        ChildCriteria = childCriteria;
    }

    public string Title { get; set; }
    public int NumberOfEvents { get; set; }
    public IEnumerable<ICriteriaDetail> ChildCriteria { get; set; }
}

2)将xaml更改为

<TreeView ItemsSource="{Binding Criterias}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding ChildCriteria}">
                <TextBlock Foreground="Red" Text="{Binding Title}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
</TreeView>

3)将GetCriteriaDetail更改为

    private static ICriteriaDetail GetCriteriaDetail(string title, int events, bool hasChild)
    {
        if (!hasChild)
            return new CriteriaDetail(title, events, null);

        var child3 = new CriteriaDetail("child3" + title, 13 + events, null);
        var child2 = new CriteriaDetail("child2" + title, 13 + events, new ICriteriaDetail[] { child3 });
        var child1 = new CriteriaDetail("child1" + title, 13 + events, new ICriteriaDetail[] { child2 });


        return new CriteriaDetail(title, events, new ICriteriaDetail[] {child1});
    }

得到了这个。我觉得它看起来更像你想要的 result