在具有 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}"。它不需要隐藏代码来在框架中显示页面。
如前所述,它已经过测试并且可以工作,输出中也没有错误。
我有一个具有多项功能的程序。每个功能都有一个 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}"。它不需要隐藏代码来在框架中显示页面。 如前所述,它已经过测试并且可以工作,输出中也没有错误。