【问题标题】:Data binding with x:Bind to a List in UWP app使用 x 进行数据绑定:绑定到 UWP 应用中的列表
【发布时间】:2018-04-10 13:55:27
【问题描述】:

对 UWP 来说相当新,但对 c# 来说不是,并且存在数据绑定问题。 我正在尝试生成一个文件列表,我确信这很容易,但我显然遗漏了一些东西。

我有 ViewModel:

namespace FileThing.ViewModels
    class FolderContext : INotifyPropertyChanged
{
    public StorageFolder SelectedFolder;
    public ICollection<StorageFile> FileList;

    public async Task<bool> GetFileList()
    {
        if (SelectedFolder != null)
        {
            // Get the file list
            FileList =  (ICollection<StorageFile>) await SelectedFolder.GetFilesAsync();
            return true; // Success..
        }
        else
        {
            return false;  // there was an error
        }

    }

  more stuff....

}

我的 XAML 看起来像:

<Page
x:Class="FileThing.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FileThing"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:data ="using:FileThing.ViewModels"
mc:Ignorable="d" FontSize="16" >

<StackPanel>
    <StackPanel Orientation="Vertical" Margin="10,10,10,10">
        <TextBlock Name="NextStep" Text="Please Select a Folder to Process"/>
        <Button Name="FolderButton" Click="FolderButton_ClickAsync" Margin="20,20,20,20">
            <StackPanel Orientation="Horizontal">
                <TextBlock FontFamily="Segoe MDL2 Assets"  Text="&#xE8B7;"/>
                <TextBlock Text="Set Folder" />
            </StackPanel>
        </Button>
        <!--<Button Name="FolderButton" Content="Set Folder" Click="FolderButton_ClickAsync" Margin="0,0,20,0"/>-->
        <TextBlock Name="SelectedFolderPath" Text="No Folder Selected"/>
    </StackPanel>

    <ListView x:Name="FileList" IsItemClickEnabled="True" ItemsSource ="{x:Bind fc.FileList}">
        <ListViewHeaderItem>
            <TextBlock Name="Status" Text="Nothing to report so far"/>
        </ListViewHeaderItem>
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="data:FolderContext">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Name="Path" Text="{x:Bind FileList.Path}"/>
                    <TextBlock Name="FileName" Text="{x:Bind FileList.Name}"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>


</StackPanel>

主页背后的代码是:

   public sealed partial class MainPage : Page
{
    FolderContext fc = new FolderContext();

    public MainPage()
    {
        this.InitializeComponent();

    }

    private async void FolderButton_ClickAsync(object sender, RoutedEventArgs e)
    {
        fc.SelectedFolder = await Helpers.GetFolder();
        SelectedFolderPath.Text = fc.SelectedFolder.Path;
        Status.Text = "Loading Files ...";
        bool filesloaded = await fc.GetFileList();
        if (!filesloaded)
        {
            NextStep.Text = "There was an Error Please try again or select another folder";
        }
        else
        {
            Status.Text = "File List Loaded successfully with " + fc.FileList.Count + " files found";
        }
    }
}

因此,用户按下 Selectfolder 按钮,代码成功执行此操作并返回“StorageFile”对象列表 - 我有一个单独的问题,即 StorageFiles 是否对我想要的东西来说有点太重(简单分析但很多文件)... 我的错误是: 无效的绑定路径“FileList.Path”:在类型“ICollection”FileThing 上找不到属性“Path” 我对 FileList.Name 有相同的错误,它们都是 StorageFile 对象的有效属性。引用 ItemTemplate 的内部 TextBlock 行。

我尝试过使用其他集合类型; List,IList,ObservableCollection(我认为是为了节省 Inotifychanged 的​​骚扰?,但我认为我错过了一些更基本的东西。 我确信这是一个简单的新手错误 - 任何想法......

【问题讨论】:

  • 我已经设法部分完成了这项工作.. 基本上将 FileList 放在 MainPage 代码后面。但是,如果我引用类型为 FolderContext 的 fc 类并在其中包含 FileList 则不起作用...也许您只是不能引用子对象...?但这似乎并不明智。

标签: c# data-binding uwp


【解决方案1】:

您错误地使用了 x:bind。为了更好地理解,我建议你从Data binding主题和{x:Bind} markup extension文档中学习。

{x:Bind} 使用页面或用户控件本身作为默认源。因此,它将在您的页面或用户控件的代码隐藏中查找属性、字段和方法。此外,当使用 {x:Bind} 和数据模板时,您必须通过设置 x:DataType 值来指示要绑定的类型,并且 DataType 应该包含相应的属性,您在 DataTemplate 中绑定的字段和方法。您还可以将类型设置为接口或基类类型,然后在必要时使用强制转换来制定完整的表达式。

对于您的问题,您的 x:DataType 应该是 StorageFile 类更合适,而 TextBlock Text 属性可以直接绑定 PathName .代码将如下所示:

<Page
    ...
    xmlns:storage="using:Windows.Storage"
    mc:Ignorable="d">
    ...
        <ListView x:Name="FileList" IsItemClickEnabled="True" ItemsSource ="{x:Bind fc.FileList}">
            <ListViewHeaderItem>
                <TextBlock Name="Status" Text="Nothing to report so far"/>
            </ListViewHeaderItem>
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="storage:StorageFile">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Name="Path" Text="{x:Bind Path}"/>
                        <TextBlock Name="FileName" Text="{x:Bind Name}"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
     ...
</Page>

【讨论】:

  • 谢谢你,我按照你的建议做了,现在它确实看到了元素。这导致的唯一问题是似乎很难将文件夹选择器返回的 IReadOnlyList 转换为 ObservableCollection ,代码构建并运行但遇到异常......:S -
猜你喜欢
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
相关资源
最近更新 更多