0

我正在尝试创建一个包含扩展器列表的视图,当我按下以扩展其中一个时,我想要一个来自要加载的不同项目源的名称列表。到目前为止,我得到的是当我将项目源设置为 LineRouteCollection 以设置扩展器的标题时,即使我绑定扩展器以显示来自 AllStopsCollection 的名称,绑定“名称”显示来自 LineRouteCollection 源的名称而不是名称根据我的需要从 AllStopsCollection 中获取。你能看看我的代码并告诉我我做错了什么吗?

<ListBox>
    <ItemsControl ItemsSource="{Binding LineRouteCollection}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander Header="{Binding Name}" MinHeight="70">                            
                    <ListBox >
                        <ItemsControl ItemsSource ="{Binding AllStopsCollection}">
                            <TextBlock Text="{Binding Name}"></TextBlock>
                        </ItemsControl>
                    </ListBox>
                </Expander>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</ListBox>

编辑:

在我的视图模型中,我像这样加载可观察的集合(AllStopsCollection 和 LineRouteCollection):

private ObservableCollection<Route> AllLineRoutes;
private ObservableCollection<StopView> AllRouteStops;

//List of all Routes connected to the selected line
public ObservableCollection<Route> LineRouteCollection // Must be property or DP to be bound!
{
    get { return AllLineRoutes; }
    set
    {
        if (Equals(value, AllLineRoutes)) return;
        AllLineRoutes = value;
    }
}


//List of all stops
public ObservableCollection<StopView> AllStopsCollection // Must be property or DP to be bound!
{
    get { return AllRouteStops; }
    set
    {
        if (Equals(value, AllRouteStops)) return;
        AllRouteStops = value;
    }
}

我在类的构造函数中用数据填充集合。我正在正确加载数据,我可以看到它,但在展开器展开后它不会出现在文本框中。

4

2 回答 2

1

您为第一个提供ItemTemplate了一个ItemsControl,但内部ItemsControl包含一个TextBlock只是嵌套在控件内的

您还需要ItemTemplate为内部控件指定一个

<ListBox>
    <ItemsControl ItemsSource="{Binding LineRouteCollection}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander Header="{Binding Name}" MinHeight="70">                            
                    <ListBox>
                        <ItemsControl ItemsSource ="{Binding AllStopsCollection}">
                            <ItemsControl.ItemTemplate> <!-- You forgot this ItemTemplate -->
                                <DataTemplate>
                                    <TextBlock Text="{Binding Name}"></TextBlock>
                               </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                   </ListBox>
                </Expander>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</ListBox>

否则,最内部的绑定范围将与TextBlock内部相同,ItemsControl从而导致您看到的问题

不知道为什么你有一个ItemsControl内部ListBox虽然..?您想要多个ExpandersListBox不是单个列表项吗?

这对我来说很好用:

    <ListBox ItemsSource="{Binding LineRoutes}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Expander Header="{Binding Name}" MinHeight="70">
                    <ListBox ItemsSource ="{Binding AllStops}">
                            <ListBox.ItemTemplate>
                                <!-- You forgot this ItemTemplate -->
                                <DataTemplate>
                                    <TextBlock Text="{Binding Name}"></TextBlock>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                    </ListBox>
                </Expander>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

列表框中的嵌套扩展器示例

那是你想要的吗?

编辑:

好的,根据您的更新,我可以看到错误是什么

您希望密切注意输出窗口中的绑定错误。

AllStopsCollection不是子级,所以LineRouteCollectionforDataContext内部控件指向 a Routenot the ViewModel

为了绑定到Stops 的集合,您需要确保将绑定指向具有ViewModelas it's的控件DataContext。最简单的方法是使用ElementName绑定并绑定到根控件(通常称为LayoutRoot

例如

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:wpfApplication1="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" d:DataContext="{d:DesignInstance wpfApplication1:ViewModel}">
    <Grid Name="LayoutRoot">
        <ListBox ItemsSource="{Binding LineRouteCollection}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Expander Header="{Binding Name}" MinHeight="70">
                        <ListBox ItemsSource ="{Binding DataContext.AllStopsCollection, ElementName=LayoutRoot}"> <!-- Provide an ElementName binding to point to the root Grid and bind to the viewmodels AllStopsCollection (viewmodel is in the DataContext) -->
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Name}"></TextBlock>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ListBox>
                    </Expander>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

希望有帮助

唯一需要注意的是,如果您需要操作停止 - 显然,因为您将同一个集合绑定到多个子列表,如果您更改一个Stop项目,它也会更改每个列表中的值,因为引用全部指向同一个对象

于 2014-09-05T12:04:28.277 回答
-1

这是一种方法,尝试变得更有活力。这是一个列表框,我在其中预定义了 3 个不同的文本框并在运行时提供值。

<ListBox x:Name="ListBox1" HorizontalAlignment="Left" Height="253" Margin="10,28,0,0" VerticalAlignment="Top" Width="734">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid x:Name="grid" Margin="0,2">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="234" />
                                    <ColumnDefinition Width="143" />
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" HorizontalAlignment="Left" Text="{Binding String1}"/>
                                <TextBlock Grid.Column="1" HorizontalAlignment="Left" Text="{Binding String2}" TextTrimming="WordEllipsis"/>
                                <TextBlock Grid.Column="2" HorizontalAlignment="Left" Text="{Binding String3}"/>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

代码背后:

    public class Class1
    {
        public string String1 { get; set; }
        public string String2 { get; set; }
        public string String3 { get; set; }
    }

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
            ListBox1.Items.Add((new Class1()
            {
                String1 = "Apple",
                String2 = "Car",
                String3 = "Tree"
            }));
    }

或者

如果您想要一个在运行时更加动态的解决方案,您可以执行以下操作:

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
                Grid WholeGrid = new Grid();
                WholeGrid.HorizontalAlignment = HorizontalAlignment.Left;
                ColumnDefinition colDef1 = new ColumnDefinition();
                ColumnDefinition colDef2 = new ColumnDefinition();
                ColumnDefinition colDef3 = new ColumnDefinition();
                WholeGrid.ColumnDefinitions.Add(colDef1);
                WholeGrid.ColumnDefinitions.Add(colDef2);
                WholeGrid.ColumnDefinitions.Add(colDef3);

                // Create Question Lable
                Label QuestionLabel = new Label();
                QuestionLabel.Content = "Apple";
                Grid.SetRow(QuestionLabel, 0);
                Grid.SetColumn(QuestionLabel, 0);

                // Create Date Picker
                DatePicker newDatePicker = new DatePicker();
                newDatePicker.Width = 200;
                newDatePicker.Height = 20;
                Grid.SetRow(newDatePicker, 0);
                Grid.SetColumn(newDatePicker, 1);

                // Add to Lable and Date Picker
                WholeGrid.Children.Add(QuestionLabel);
                WholeGrid.Children.Add(newDatePicker);
                ListBox1.Items.Add(WholeGrid);
    }
于 2014-09-05T11:53:20.213 回答