【问题标题】:UWP - Correct way to implement INotifyPropertyChanged?UWP - 实现 INotifyPropertyChanged 的​​正确方法?
【发布时间】:2020-09-28 13:40:05
【问题描述】:

我正在尝试创建各种 UWP 秒表,但我一直在更新 UI。

下面是我的模型文件夹中的基本秒表类

public class KuStopWatch : INotifyPropertyChanged
{
    public string Name { get; set; }
    public DateTime DateCreated = DateTime.UtcNow;
    public Guid Id = Guid.NewGuid();
    public List<TimeSpan> Laps;
    public Stopwatch SwInstance = new Stopwatch();
    public TimeSpan SavedState { get; set; }
    public DateTime TimeStarted { get; set; }
    private string _elapsed;
    public string Elapsed
    {
        get { return _elapsed; }
        set { _elapsed = value;
            NotifyPropertyChanged();
        }
    }
    public bool ClosedWhileRunning { get; set; }

    public void Start()
    {
        TimeStarted = DateTime.UtcNow;
        var tmr = new Timer() { Interval = 16, AutoReset = true };
        tmr.Start();
        tmr.Elapsed += (s, e) => {
                Elapsed = ElapsedString();
            };
        SwInstance.Start();
    }
    ...
    public string ElapsedString()
    {
        var time = SwInstance.Elapsed + SavedState;
        return time.ToString(@"hh\:mm\:ss\:ff");

    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

这是我的“ViewModel”

public class StopwatchViewModel : ViewModelBase
{
    public ObservableCollection<KuStopWatch> SWData { get; } = new ObservableCollection<KuStopWatch>();
    public StopwatchViewModel()
    {
        //Dummy
        SWData.Add(new KuStopWatch());
        SWData[0].Start();
    }
}

还有我的 XAML

<Page
x:Class="MyApp.Views.StopwatchPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:MyApp.Models"
Style="{StaticResource PageStyle}"
mc:Ignorable="d">
<Page.Resources>
    <DataTemplate x:Key="StopwatchTemplate" x:DataType="models:KuStopWatch">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock
                Grid.Row="0"
                Grid.Column="1"
                Style="{ThemeResource BaseTextBlockStyle}"
                Text="{Binding Path=Elapsed, UpdateSourceTrigger=PropertyChanged}" />
            <Button
                Grid.Row="2"
                Grid.Column="1"
                Style="{StaticResource ButtonRevealStyle}">
                <SymbolIcon Symbol="Play" />
            </Button>

        </Grid>
    </DataTemplate>
</Page.Resources>
<Grid x:Name="ContentArea" Margin="{StaticResource MediumLeftRightMargin}">
    <controls:AdaptiveGridView
        x:Name="StopwatchViewGrid"
        Background="Transparent"
        ItemTemplate="{StaticResource StopwatchTemplate}"
        ItemsSource="{Binding}"
        OneRowModeEnabled="False" />
</Grid>

数据上下文设置为 ViewModel.SWData。

我得到的当前行为是 UI 中的时间仅在我来回切换页面时更新。我搞砸了 INotify... 的方式导致“应用程序调用了一个为不同线程编组的接口”。例外,无论我尝试什么。有谁知道这样做的正确方法吗?

【问题讨论】:

  • 接口按照它应该的方式实现,绑定也是。我可以想象计时器有问题,但我从未使用过
  • 这很粗糙。您还有其他想法如何实时更新秒表视图吗?我能想到的只是设置一个计时器或使用 sleep() 循环
  • 尝试使用 DispatcherTimer。它应该在 UI 线程中运行,而不是在线程池中,就像 Timer 一样
  • 你完全正确!在使用 DispatcherTimer 时,它确实按预期工作。所以这毕竟是一个线程问题。谢谢。

标签: c# mvvm uwp


【解决方案1】:

INotifyPropertyChanged 已按应有的方式实现。问题是定时器。使用 DispatcherTimer,它使用 UI Thread 而不是线程池,例如 Timer

【讨论】:

    猜你喜欢
    • 2017-06-20
    • 1970-01-01
    • 2011-12-03
    • 2010-09-21
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多