在具有 XAML 绑定的 ListView 中显示页面列表

Show a list of pages in ListView with XAML binding

我有一个具有多项功能的程序。每个功能都有一个 ViewModel、一个 MainView 和 OptionsView。 MainView 显示功能的作用,而 OptionsView 是一个允许用户更改功能设置的视图。 OptionsView 存储在 MainView 中。

我想将选项集中到 ListView 下的 MainOptions 视图中。我可以获得每个功能的 MainViews 的列表或 ObservableCollection,但是我无法获取每个功能的 OptionsView。

我可以很好地在 MainView 中显示 OptionsView,但是当我尝试在 ListView 中使用 DataTemplate 以便将 MainView 列表绑定到它并获取 OptionView 时,它不显示任何内容,但它不会' t 崩溃或输出错误。

OptionsMain 的

XAML :

<Grid>
    <ListBox Name="OptionsList" ItemsSource="{Binding Path=FeaturesPages, Mode=TwoWay}" Background="Transparent">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Frame Name="GroupItemFrame" Content="{Binding Path=OptionsPage, Mode=TwoWay}"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

隐藏代码:

public partial class OptionsMain : Page, INotifyPropertyChanged
{
    private ObservableCollection<Page> _optionsPages = new ObservableCollection<Page>();

    public ObservableCollection<Page> OptionsPages
    {
        get { return _optionsPages; }
        set
        {
            _optionsPages = value;
            NotifyPropertyChanged("OptionsPages");
        }
    }

    public OptionsMain(ObservableCollection<Page> pages)
    {
        foreach (Page p in pages)
        {
            OptionsPages.Add(p);
        }
        Console.WriteLine("List size : {0}", OptionsPages.Count);
        InitializeComponent();
        DataContext = this;

对可能是什么问题有任何见解吗?有更好的方法吗?

这是一个棘手的问题,我没有看到很多方法来完成它,但我确实有办法。问题是您需要为每一帧调用 Frame.Navigate 到页面。您不能只分配内容,除非它实际上是一个包含内容的控件。因此,我将建议一项工作 around/hack 强制框架在加载时进行导航。

Mainpage.xaml:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListBox Name="OptionsList" Background="Transparent">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Frame Name="GroupItemFrame" Loaded="GroupItemFrame_Loaded" Width="100" Height="100" BorderBrush="Red" BorderThickness="2" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

Mainpage.xaml.cs:

  public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        List<Page> MyPages = new List<Page>();
        MyPages.Add(new DisplayNumberPage());
        MyPages.Add(new DisplayNumberPage());
        MyPages.Add(new DisplayNumberPage());
        MyPages.Add(new DisplayNumberPage());
        MyPages.Add(new DisplayNumberPage());
        OptionsList.ItemsSource = MyPages;
    }

    int Index = 1;
    private void GroupItemFrame_Loaded(object sender, RoutedEventArgs e)
    {
        Frame MyFrame = sender as Frame;
        MyFrame.Navigate(typeof(DisplayNumberPage), Index);
        Index++;
    }
}

DisplayNumberPage.xaml:

<Grid Background="Black">
    <TextBlock x:Name="DisplayNumber" FontSize="30" Text="100" Foreground="White"/>
</Grid>

DispayNumberPage.xaml.cs:

  public sealed partial class DisplayNumberPage : Page
{
    public DisplayNumberPage()
    {
        this.InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        DisplayNumber.Text = e.Parameter.ToString();
    }
} 

我将此添加为答案,以便它可见。 在使用标记为正确的答案后,我找到了问题的最佳答案。它们都有效,这只是另一种方式,我认为更简单,可以达到相同的结果:

 <ListBox Name="OptionsList" ItemsSource="{Binding Path=OptionsPages, Mode=TwoWay}" Background="Transparent">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <StackPanel Name="OptionsItemStack" Orientation="Vertical">
                        <Label Name="GroupItemLabel" Content="{Binding Path=Title, Mode=OneWay}" Foreground="White"/>
                        <Frame Name="GroupItemFrame" Content="{Binding}"/>
                    </StackPanel>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>

注意 Content="{Binding}"。它不需要隐藏代码来在框架中显示页面。 如前所述,它已经过测试并且可以工作,输出中也没有错误。