XAML 从ViewModel中的绑定属性部分更新WPF文本块

8fsztsew  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(104)

我的代码中有一个相当奇怪的行为。我设计了一个Textblock,用一个数字来表示两个for循环的进度百分比。
50%的进展由IProgress报告基因从一个循环中报告,然后剩余的50%由第二个循环使用相同的IProgress报告基因报告。
循环的代码是这样的:

public List<List<string[]>> PopulateSourceList(Sources refSources, CancellationToken cancellationToken=default, ObservableCollectionEx<ISourceModel> NormalReferenceSourceItems = null, ObservableCollectionEx<ISourceModel> CourtCaseSourceItems = null, IProgress <Interfaces.Model.ProgressReport> sourceUpdateProgressReporting = null)
{
    Sources sources = refSources;
    int sourcesCount = sources.Count;
    List<NormalReferenceSourceModel> normalRefSources = new List<NormalReferenceSourceModel>();
    List<CourtCaseSourceModel> courtRefSources = new List<CourtCaseSourceModel>();

    for (int s = 1; s <= sourcesCount; s++)
    {
        if (cancellationToken.IsCancellationRequested)
        {
            cancellationToken.ThrowIfCancellationRequested();
        }
        Source source = sources[s];
        string cited = source?.Cited == true ? "YES" : "NO";
        string title;
        string year;
        try
        {
            title = source.Field["Title"];
        }
        catch (Exception)
        {
            title = string.Empty;
        }
        try
        {
            year = source.Field["Year"];
        }
        catch (Exception)
        {
            year = string.Empty;
        }
        string[] results = new string[] { authorBuilder.ToString(), title, cited, tag, year };
        if (caseType.Equals("case"))
        {
            courtRefSources?.Add(new CourtCaseSourceModel(authorBuilder.ToString(), title, cited, tag, year));
            cases.Add(results);
        }
        else
        {
            normalRefSources?.Add(new NormalReferenceSourceModel(authorBuilder.ToString(), title, cited, tag, year));
            items.Add(results);
        }
        int percentageP = (int)(Math.Round(s/(double)sourcesCount, 2) * 50);
        sourceUpdateProgressReporting.Report(new ProgressReport("SourcesExtraction", percentageP, 100));
    }

    if(NormalReferenceSourceItems != null)
    {
        normalRefSources.Sort();
        int articlesSourceCount = normalRefSources.Count;
        for (int a = 0; a < articlesSourceCount; a++)
        {
            NormalReferenceSourceItems.Add(normalRefSources[a]);
            int cuurentPercentage = 50 + (int)(Math.Round(a / (double)articlesSourceCount, 2) * 50);
            sourceUpdateProgressReporting.Report(new ProgressReport("SourcesExtraction", cuurentPercentage, 100));
        }
        sourceUpdateProgressReporting.Report(new Interfaces.Model.ProgressReport("Done", 100, 100));
    }
}

字符串
对于IProgress报告器发送的每个报告,都会调用EventHandler。WPF ViewModel订阅该事件,并且绑定到TextBlockText的属性在事件侦听器中更新。报告的前半部分(50%)会在View中成功捕获和更新,但随后它会停止在那里,并且永远不会更新剩余的50%。
ViewModel中监听事件的方法如下:

private void OpenDocumentModel_SourceUpdateProgressChangedEvent(object sender, Interfaces.Helpers.SourceUpdateProgressEventArgs e)
{
    if (!ReportProgress) return;
    if (!e.ProgressState.Equals("Done"))
    {
        UpdateProgress = $"{(int)e.Value}%";
    }
    else
    {
        UpdateProgress = $"{(int)e.Value}%";
        UpdateProgress = string.Empty;
        ReportProgress = false;
        CenitxVisibility = "Visible";
        ProgressBarVisibility = "Collapsed";
    }
}


UpdatePrgress是绑定到TextBlock的属性。
属性从setter成功更新,但只有前50%在TextBlock本身上反映,当最终进度报告发送时。但奇怪的是,将UpdateProgress属性设置为string.empty的最后调用由TextBlock反映,View最终成功更新。
最后一个调用是携带“完成”作为进度状态的调用,由以下各项触发:

sourceUpdateProgressReporting.Report(new Interfaces.Model.ProgressReport("Done", 100, 100));


有没有人知道为什么会发生这种情况?

xienkqul

xienkqul1#

好吧,对我来说,这似乎只是因为程序运行“太快”。
我没有太多的细节,所以如果你能告诉我们SourcesNormalReferenceSourceItems中通常有多少项,那会很有帮助。
我的理论是你的循环

for (int a = 0; a < articlesSourceCount; a++)
{
     NormalReferenceSourceItems.Add(normalRefSources[a]);
     int cuurentPercentage = 50 + (int)(Math.Round(a / (double)articlesSourceCount, 2) * 50);
     sourceUpdateProgressReporting.Report(new ProgressReport("SourcesExtraction", cuurentPercentage, 100));
}

字符串
在你有时间注意文本框中的变化之前就完成了。现在,如果你已经尝试过延迟或类似的事情,那么我会很有帮助。你能够看到string.empty的最终变化是因为它是最后一次,因此是永久性的变化。
这可能都是错误的,但在这种情况下,如果你给予给我们一个在测试运行中传递到方法中的数据的种类/大小的概述,我将不胜感激。

相关问题