【问题标题】:UWP # not showing ListView.ItemTemplate since I changed from List to ObservableCollection and asyncUWP # 不显示 ListView.ItemTemplate,因为我从 List 更改为 ObservableCollection 和异步
【发布时间】:2017-03-03 19:41:25
【问题描述】:

我有一个带有手动创建列表的有效解决方案。 但是由于我想从文件中读取,因此我不得不更改为异步,并且因为数据量将来会更改为 ObservableCollection,所以 XAML 不再显示 9 行。

调试我看到 {x:Bind Accounts} 仍然包含 9 行和两个值。但 AccountNameSumAccountName 数据并未列出。只有页眉和页脚。 我现在花了几个小时比较这两种解决方案,但不知道为什么这个不显示数据。

Overview.xaml:

x:Class="Finance_Manager.Overview"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Finance_Manager"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:data="using:Finance_Manager.Models"
mc:Ignorable="d">

<StackPanel>
        <Grid Margin="20,20,20,20" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Loaded="Grid_Loaded">
        <ListView ItemsSource="{x:Bind Accounts}" IsItemClickEnabled="True" ItemClick="ListView_ItemClick">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.Header>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="4*" />
                        <ColumnDefinition Width="1*" />
                    </Grid.ColumnDefinitions>
                    <TextBlock FontWeight="Bold" Text="Konto" />
                    <TextBlock Grid.Column="1" FontWeight="Bold" Text="Total" TextAlignment="Right"/>
                </Grid>
            </ListView.Header>
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="data:Account">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="4*" />
                            <ColumnDefinition Width="1*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{x:Bind AccountName}" />
                        <TextBlock Grid.Column="1" Text="{x:Bind SumAccountName}" TextAlignment="Right"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.Footer>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="4*" />
                        <ColumnDefinition Width="1*" />
                    </Grid.ColumnDefinitions>
                    <TextBlock FontWeight="Bold" Text="Gesamtvermögen" />
                    <!-- <TextBlock Grid.Column="1" FontWeight="Bold" x:Name="SumTextBlock" TextAlignment="Right"/> -->
                    <TextBlock Grid.Column="1" FontWeight="Bold" Text="CHF 326'979.74" TextAlignment="Right"/>
                </Grid>
            </ListView.Footer>
        </ListView>
    </Grid>
    <Grid>
        <TextBlock Margin="20,80,0,0" x:Name="TextBlockClicked" TextWrapping="Wrap" VerticalAlignment="Bottom" />
    </Grid>
    </StackPanel>

Accounts.cs:

namespace Finance_Manager.Models
{
    public class Account
    {
        public string AccountName { get; set; }
        public double SumAccountName { get; set; }
    }

    public class AccountOverview
    {
        public static async Task<ObservableCollection<Account>> GetAccounts()
        {
            var accounts = new ObservableCollection<Account>();

            //
            // Load file
            var folder = ApplicationData.Current.LocalFolder;
            var GetOverviewFile = await folder.GetFileAsync("overview.json");
            string jsonString = await FileIO.ReadTextAsync(GetOverviewFile);
            //

            JsonArray root = JsonValue.Parse(jsonString).GetArray();
            for (uint i = 0; i < root.Count; i++)
            {
                string account1 = root.GetObjectAt(i).GetNamedString("account");
                double sumaccount1 = root.GetObjectAt(i).GetNamedNumber("sumaccount");
                accounts.Add(new Account { AccountName = account1, SumAccountName = sumaccount1 });
            };

            //accounts.Add(new Account { AccountName = "Bank1", SumAccountName = 100.00 });
            //accounts.Add(new Account { AccountName = "Bank2", SumAccountName = 100.00 });
            //accounts.Add(new Account { AccountName = "Bank3", SumAccountName = 100.00 });
            //accounts.Add(new Account { AccountName = "Bank4", SumAccountName = 100.00 });
            //accounts.Add(new Account { AccountName = "Bank5", SumAccountName = 100.00 });
            //accounts.Add(new Account { AccountName = "Bank6", SumAccountName = 100.00 });
            //accounts.Add(new Account { AccountName = "Bank7", SumAccountName = 100.00 });
            //accounts.Add(new Account { AccountName = "Bank8", SumAccountName = 100.00 });
            //accounts.Add(new Account { AccountName = "Bank9", SumAccountName = 100.00 });

            return accounts;
        }
    }
}

Overview.xaml.cs:

namespace Finance_Manager
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class Overview : Page
    {

        public ObservableCollection<Account> Accounts;

        public Overview()
        {
            this.InitializeComponent();
        }

        public async void Grid_Loaded(object sender, RoutedEventArgs e)
        {
            Accounts = await AccountOverview.GetAccounts();
        }
    }
}

【问题讨论】:

    标签: c# xaml asynchronous uwp observablecollection


    【解决方案1】:

    1) 将您的 Accounts 字段更改为属性

    2) 如果您使用绑定,则应在每次更改 Accounts 属性时实现 INotifyPropertyChanged 并调用 OnPropertyChanged()。这将更新视图。

    3) 默认情况下x:Bind 使用mode=OneTime,您应该将其更改为Mode=OneWay

    如果您想要最快、最简单的解决方案,请删除绑定并执行ListView.ItemSource = MyClass.GetAccounts()。这对 MVVM 模式不好,但我看到你在使用后面的代码。

    【讨论】:

    • 将字段更改为属性非常简单 - public ObservableCollection&lt;Account&gt; Accounts {get; set;}
    【解决方案2】:

    首先,绑定仅适用于属性而非字段(您的 ObservableCollection Accounts 只是字段)。

    另一个问题可能是在加载 XAML 时 Accounts 属性将是 null,因此您可能需要在 this.InitializeComponents(); 之前添加 Accounts = new ObservableCollection&lt;Accounts&gt;(); 并且不要从 @987654325 返回 ObservableCollection 的全新实例@ 方法,但只是填充已经存在的对象。

    【讨论】:

    • 感谢您的回答!我现在有点挣扎。我使用了 Channel9 中的示例“绝对初学者的 Windows 10 开发”。如何将帐户从字段更改为属性?没有找到与我不同的示例。
    • 在您的情况下,只需将 public ObservableCollection&lt;Account&gt; Accounts; 更改为 public ObservableCollection&lt;Account&gt; Accounts { get; set; }
    【解决方案3】:

    我做了所有解释,但它仍然不起作用。

    我在 Overview.xaml 中的 ListView 中添加了 Name="AccountList"。和 AccountList.ItemSource = Accounts; 到 Overview.xaml.cs。现在可以了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-20
      • 1970-01-01
      • 2013-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多