gpt4 book ai didi

c# - 在 ICommand 操作期间更新标签

转载 作者:行者123 更新时间:2023-12-03 10:58:15 24 4
gpt4 key购买 nike

在 WPF 中,使用 MVVM 设计,我创建了一个屏幕,用于将大量日志加载到 ListView 中。点击一个按钮。返回时,标签会更新以显示返回的日志数量。此过程有时可能需要一段时间。我们的 DA 正在进行优化,但同时我需要进行以下更改以向用户指示搜索正在运行:

  • 将鼠标显示为 WaitCursor .
  • 更新标签文本以显示“正在搜索...”。

  • 我有一个实现 ICommand 的类我有 WaitCursor正常工作。但是,我无法获得更新标签以在搜索运行时显示的所需行为。我当前的代码:

    MyScreen.xaml
    <Button 
    Name="DisplayButton"
    Content="Display Logs"
    Command="{Binding DisplayLogsCommand}"
    Margin="0,64,10,0"
    VerticalAlignment="Top"
    HorizontalAlignment="Right"
    Width="112"/>
    <Label
    Content="{Binding LogsShowingText}"
    Margin="0,0,127,8"
    Foreground="#FF3C3B3B"
    HorizontalAlignment="Right"
    Width="145" Height="24"
    VerticalAlignment="Bottom"
    HorizontalContentAlignment="Right"
    FontSize="11"/>

    MyScreenVM.cs
    private Command displayLogsCommand;
    private string logShowingText;

    public Command DisplayLogsCommand
    {
    get
    {
    if (this.displayLogsCommand == null)
    {
    // Attempt 3 made here.

    bool useWaitCursor = true;

    Func<bool> canExecute = () => this.ValidateFields();

    Action execute = () =>
    {
    /*
    * TODO: Update this.LogsShowingText to read "Searching..."
    */

    // Attempt 1 and 2 made here.
    LogEntry[] entries = this.ClientConnection.GetLogs();

    this.LogsShowingText = string.Format("Showing {0} Logs", entries.Length);
    this.FilteredEntries = new ObservableCollection<LogEntry>(entries);
    };

    this.displayLogsCommand = new Command(useWaitCursor, canExecute, execute);
    }

    return this.displayLogsCommand;
    }
    }

    public string LogsShowingText
    {
    get
    {
    return this.logsShowingText;
    }
    set
    {
    this.logsShowingText= value;
    OnPropertyChanged("LogsShowingText");
    }
    }

    到目前为止,结果和我相关的失败尝试如下:
  • 之后 返回日志,标签仅显示“正在搜索...”。
    Application.Current.Dispatcher.Invoke(new Action(() => this.LogsShowingText = "Searching..."));
  • 之后 返回日志,标签仅显示“显示 N 条日志”。
    this.LogsShowingText = string.Format("Searching...");
  • 之前 期间搜索,标签为“正在搜索...”,然后是 之后 返回日志,标签读取“显示 N 条日志”。与#2 相同的代码,不同的位置。

  • 我知道这可能与 UI 在操作完成之前被阻止有关,这清楚地解释了尝试 1 显示对标签的最后排队更新和尝试 2 显示对标签的最后硬编码更新。尝试 3 几乎可以工作,但在用户单击按钮执行搜索之前不应更新标签。我怎样才能做到这一点?

    最佳答案

    由于这是一个昂贵的命令,这意味着 UI 在处理时会挂起,因此您应该将其转换为异步命令。

    public Command DisplayLogsCommand
    {
    get
    {
    if (this.displayLogsCommand == null)
    {
    bool useWaitCursor = true;
    Func<bool> canExecute = () => this.ValidateFields();

    Action execute = async () =>
    {
    this.LogsShowingText = "Searching";

    // Attempt 1 and 2 made here.
    LogEntry[] entries = await Task<LogEntry[]>.Run(() => this.ClientConnection.GetLogs());

    this.LogsShowingText = string.Format("Showing {0} Logs", entries.Length);
    this.FilteredEntries = new ObservableCollection<LogEntry>(entries);
    };

    this.displayLogsCommand = new Command(useWaitCursor, canExecute, execute);
    }

    return this.displayLogsCommand;
    }
    }

    通过制作 Action委托(delegate)异步,您现在可以在 Action 中等待.这使您可以将对 DataLayer 的调用包装在 Task 中。并等待它。现在,昂贵的操作正在 UI 线程之外运行,您的标签将在前后正确更新。无需使用 Dispatcher 编码更改。

    这将仅在用户单击按钮执行命令时更新标签。

    关于c# - 在 ICommand 操作期间更新标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31254305/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com