簡體   English   中英

Xamarin UWP 似乎綁定到錯誤的視圖 model

[英]Xamarin UWP seems to bind to the wrong view model

我有一個 Xamarin 項目,用於 Android 和 UWP。 這個問題似乎只發生在 UWP 上。

在我的 Xamarin 項目中,我將ContentPage與視圖 model 綁定為上下文。 在這個 ViewModel 中有一個帶有另一種視圖 model 的ObservableCollection 當我創建這個底層 ViewModel 的新實例並添加到我的 ObservableCollection 時,有時ContentPage會按預期工作,在我的 ListView 中顯示一個項目。 但有時會添加一個空元素,將鼠標懸停在列表上時可以看到。 發生這種情況時,我會在 Output 選項卡中收到一堆警告。

我的DownloadsPage

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:local="clr-namespace:Downloader.Converters"
             mc:Ignorable="d"
             x:Class="Downloader.Views.DownloadsPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <local:DownloadStatusToColorConverter x:Key="downloadStatusToColor" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <RefreshView IsRefreshing="{Binding IsBusy, Mode=TwoWay}" Command="{Binding LoadItemsCommand}">
        <ListView x:Name="DownloadsListView" SelectionMode="None" ItemsSource="{Binding Downloads}" RowHeight="70">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Padding="10" BackgroundColor="{Binding DownloadStatus, Converter={StaticResource downloadStatusToColor}}">
                            <Label Text="{Binding Name}"
                                   d:Text="{Binding .}"
                                   LineBreakMode="NoWrap"
                                   Style="{DynamicResource ListItemTextStyle}"
                                   FontSize="16" />
                            <Grid Grid.Row="0" Grid.Column="0" Padding="10,0,10,0">
                                <ProgressBar BackgroundColor="Transparent"  Progress="{Binding PercentDownloaded}" HorizontalOptions="FillAndExpand" HeightRequest="20">
                                </ProgressBar>
                                <Label Text="{Binding PercentString}" HorizontalTextAlignment="Center"></Label>
                            </Grid>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </RefreshView>

</ContentPage>

DownloadsViewModel在代碼隱藏中設置為上下文,如下所示:

public partial class DownloadsPage : ContentPage
{
    private readonly DownloadsViewModel _viewModel;

    public DownloadsPage()
    {
        InitializeComponent();

        BindingContext = _viewModel = new DownloadsViewModel();

        Device.StartTimer(TimeSpan.FromSeconds(1), () =>
        {
            Device.BeginInvokeOnMainThread(() => _viewModel.RefreshDownloads());
            return true;
        });
    }
}

綁定的DownloadsViewModel

public class DownloadsViewModel : BaseViewModel
{
    public ObservableCollection<DownloadViewModel> Downloads { get; set; } = new ObservableCollection<DownloadViewModel>();
 
    public Command LoadItemsCommand { get; set; }

    public DownloadsViewModel()
    {
        Title = "Downloads";
        LoadItemsCommand = new Command(() => {
            IsBusy = true;
            Downloads.Clear();
            RefreshDownloads();
            IsBusy = false;
        });
    }

    public void RefreshDownloads()
    {
        foreach (var download in DownloadManager.GetDownloads())
        {
            var existingDownload = Downloads.FirstOrDefault(d => d.Id == download.Id);

            if (existingDownload != null)
            {
                existingDownload.UpdateValues(download);
            }
            else
            {
                Downloads.Add(new DownloadViewModel(download));
            }
        }
    }
}

ObservableCollection包含如下所示的DownloadViewModel

public class DownloadViewModel : BaseViewModel
{
    private IDownload _download;
    public DownloadViewModel(IDownload download)
    {
        UpdateValues(download);
    }

    private string _id;
    public string Id
    {
        get { return _id; }
        set { SetProperty(ref _id, value); }
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set { SetProperty(ref _name, value); }
    }

    private DownloadStatus _status;
    public DownloadStatus DownloadStatus
    {
        get { return _status; }
        set { SetProperty(ref _status, value); }
    }

    public double PercentDownloaded
    {
        get
        {
            return _download.DownloadedBytes == -1
                ? 0f
                : (double)_download.DownloadedBytes / _download.TotalBytes;
        }
    }

    public string PercentString { get => $"{(int)(PercentDownloaded * 100)} %"; }

    public void UpdateValues(IDownload download)
    {
        _download = download;
        Id = _download.Id;
        Name = _download.Name;
        DownloadStatus = _download.Status;
    }
}

我有時遇到的錯誤會導致我的 ListView 中的項目為空:

Binding: 'DownloadStatus' property not found on 'Downloader.ViewModels.DownloadsViewModel', target property: 'Xamarin.Forms.StackLayout.BackgroundColor'
Binding: 'Name' property not found on 'Downloader.ViewModels.DownloadsViewModel', target property: 'Xamarin.Forms.Label.Text'
Binding: 'PercentDownloaded' property not found on 'Downloader.ViewModels.DownloadsViewModel', target property: 'Xamarin.Forms.ProgressBar.Progress'
Binding: 'PercentString' property not found on 'Downloader.ViewModels.DownloadsViewModel', target property: 'Xamarin.Forms.Label.Text'

懸停時看到的幽靈物品

調試時,我已確認該項目已按預期添加到我的 ObservableCollection 中。

為什么有時它會在 DownloadsViewModel 而不是 DownloadViewModel 上尋找 DownloadStatus、Name、PercentDownloaded 和 PercentString?

Xamarin UWP 似乎綁定到錯誤的視圖 model

我檢查了您的代碼示例,它按預期工作。 但是我發現進度值沒有自動更新導致listview項無法顯示,我已經更新了IDownload接口添加PercentDownloaded屬性。 對於測試,它可以在 uwp 平台上工作。

問題是 ViewModel 沒有為所有屬性實現 INotifyPropertyChanged 的設置器。 源代碼在 Github 上可用,修復問題的提交就是這個

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM