RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-220553

EvgeniyZ's questions

Martin Hope
EvgeniyZ
Asked: 2023-06-02 05:40:25 +0000 UTC

更新 CanExecute 命令时线程无法访问 ViewModel 层

  • 6

简单任务:更新在事件上执行按钮的能力。

我使用MVVM 工具包编写了以下基本代码:

public partial class MainViewModel : ObservableObject
{
    public MainViewModel()
    {
        _ = Task.Run(async () =>
        {
            try
            {
                while (true)
                {
                    await Task.Delay(1000);
                    CanTest = !CanTest;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
        });
    }


    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(TestCommand))]
    private bool _canTest;

    [RelayCommand(CanExecute = nameof(CanTest))]
    public void Test()
    {

    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainViewModel();
    }
}

如您所见,这里创建了一个简单的类,它在后台旋转某个任务,并每秒更新一次属性的状态bool,根据该状态更新命令CanExecute。

为清楚起见,此代码将生成的内容:

public bool CanTest
{
    get => _canTest;
    set
    {
        if (!EqualityComparer<bool>.Default.Equals(_canTest, value))
        {
            OnCanTestChanging(value);
            OnCanTestChanging(default, value);
            OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.CanTest);
            _canTest = value;
            OnCanTestChanged(value);
            OnCanTestChanged(default, value);
            OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.CanTest);
            TestCommand.NotifyCanExecuteChanged();
        }
    }
}

public IRelayCommand TestCommand => testCommand ??= new RelayCommand(new Action(Test), () => CanTest);

也就是说,许多人都熟悉的INotifyPropertyChangedand的最基本实现。ICommand

现在问题的症结在于:
这段代码导致错误

调用线程无法访问此对象,因为另一个线程拥有此对象。

这是可以理解的,我们要离开 UI 线程,这就是为什么我们不能那么容易地使用 UI,但是如何返回呢?对于这个问题,我们有典型的解决方案,使用Dispatcher. 好吧,就说这个吧ViewModel,一个对UI一无所知的独立类,我们可以这样写一个拐杖

public MainViewModel(Dispatcher dispatcher)
{
    _ = Task.Run(async () =>
    {
        try
        {
            while (true)
            {
                await Task.Delay(1000);
                dispatcher.BeginInvoke(new Action(() => { CanTest = !CanTest; }));
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.Message);
        }
    });
}

这将解决问题,但仅此违反了 MVVM 和其他规则。使用Dispatcher.CurrentDispatcher我们也将摆脱错误,但我们的数据将不再更新,这似乎也是合乎逻辑的。其实,如何解决问题呢?

是的,属性更改本身不会导致错误,它会导致更新CanExecute(调用:TestCommand.NotifyCanExecuteChanged();),从而生成[NotifyCanExecuteChangedFor(nameof(TestCommand))]. 如果移除,按钮将不会实时更新,但bool属性值会开始变化。


PS无限await循环例如,在一个真实的项目中,我有一个服务监视进程变化(运行或不运行),并向外发送一个事件,它都在容器中注册,它从中请求ViewModel,它订阅和更新属性,收到错误。

public class ProcessWatcherService : IProcessWatcher, IDisposable
{
    private readonly HashSet<string> _monitoredProcesses = new();
    public event EventHandler<ProcessChangedEventArgs>? ProcessChanged;

    private readonly ManagementEventWatcher _startWatch;
    private readonly ManagementEventWatcher _stopWatch;

    private readonly ILogger<ProcessWatcherService> _logger;

    public ProcessWatcherService(ILogger<ProcessWatcherService> logger)
    {
        _logger = logger;

        _startWatch = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
        _startWatch.EventArrived += (_, e) => ProcessChangedEvent(e.NewEvent.Properties["ProcessName"].Value, ProcessStatus.Started);
        _startWatch.Start();

        _stopWatch = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace"));
        _stopWatch.EventArrived += (_, e) => ProcessChangedEvent(e.NewEvent.Properties["ProcessName"].Value, ProcessStatus.Stopped);
        _stopWatch.Start();
    }

    public bool Verify(string process)
    {
        var result = Process.GetProcesses()
            ?.Any(x => x.ProcessName.ToLower() == Path.GetFileNameWithoutExtension(process).ToLower()) == true;
        _logger.LogTrace("Verify process status {process} = {result}", process, result);
        return result;
    }

    public void StartWatch(string process)
    {
        _logger.LogDebug("Process {process} added to watch list", process);
        _monitoredProcesses.Add(process.ToLower());
    }

    public bool AddAndWatch(string process)
    {
        StartWatch(process);
        return Verify(process);
    }

    void ProcessChangedEvent(object name, ProcessStatus status)
    {
        if (name is string processName && _monitoredProcesses.Contains(processName.ToLower()))
        {
            _logger.LogInformation("Process {process} change status: {status}", processName, status);
            ProcessChanged?.Invoke(this, new(processName, status));
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        _startWatch.Stop();
        _stopWatch.Stop();
    }
}
c#
  • 1 个回答
  • 32 Views
Martin Hope
EvgeniyZ
Asked: 2022-09-30 23:27:01 +0000 UTC

如何判断目录是否已重命名?

  • 1

需要创建一些机制来更新项目。出于这些目的,我想做以下逻辑:

  • 目录A和B(新版本)都在同一台计算机上,检查它们的差异,创建一种差异“地图”。
  • 地图指定了路径、大小、散列和一些动作。
  • 操作是需要对此文件/目录执行的操作(重命名、删除、替换、解包、将数据附加到文件等)
  • 结果,生成的“地图”和带有修改文件的存档被发送到客户端。

也就是说,如果目录A包含

- FirstFolder
  - lib1.dll
  - lib2.dll
  - lib3.dll
- SecondFolder
  - SomeLib.dll
  - SomeData.db

和目录B

- FirstFolder
  - lib1.dll
  - lib2.dll
- SecondNewFolder
  - SomeLib.dll

然后我们看到在B(新版本)SecondFolder中它被重命名为SecondNewFolder并且文件被从中删除SomeData.db,好吧,也没有文件lib3.dll来自FirstFolder。粗略地说,快照(“地图”)将是这样的:

- delete "/FirstFolder/lib3.dll"
- rename "/SecondFolder" "/SecondNewFolder"
- delete "/SecondNewFolder/SomeData.db"

其实,现在的问题是:如何判断目录SecondFolder是改名了还是没有删除?
毕竟,如果我们把所有文件和目录的列表,通过它们的存在、大小、哈希进行比较,那么检查将找不到目录,它会认为重命名为“新”,这会导致错误的结论,像这样:

- delete "/FirstFolder/lib3.dll"
- delete "/SecondFolder"
- create "/SecondNewFolder"
- unzip  "/SecondNewFolder.zip" "/SecondNewFolder"

而这反过来又会导致补丁的大小增加、不必要的操作、长时间的安装等等,因为每个目录都可能有好几千兆字节,并且会打包那些已经在客户端计算机上的文件没有变化,好吧,这样的职业。

psFileSystemWatcher我知道,但它不适合一个简单的原因 - 新版本由几个人组装,很长一段时间,启动一个监控所有更改的进程并不是非常可取的。


补充:

  • 此实用程序是为由社区开发的 Skyrim 创建的。有一位作者用他的修改、翻译和其他东西创建了自己的程序集。人们有权安装第三方模组,移除不必要的模组等。目的是通过更新“核心”,即它是什么,将作者的更改传递给人们,而不影响用户更改(你不能删除不在原始文件中的文件夹和文件)。

  • 不幸的是,不可能将文件分为“用户”和“原始”。

  • 修改可以不同,它们的目录只能包含 2 个文件,或者可能有几百个小文件(纹理、声音等)。

  • 在两个不同的模组(目录)中,可能有重复的文件。

  • 为什么不考虑重命名“新”?安装修改时,它的名称(和目录名称)将从存档或修改站点中获取,有时它包含很多额外的东西(注意:)8k Texture 2021_RU_89а770407р。碰巧你不注意它,把它给了有这种名字的人,有一天你想把它重命名8k Texture 2021_RU_89а770407р为8k Texture. 是的,只有 8k 纹理可以重 5++ GB,如果程序认为这是“新的”,那么当他需要做的就是重命名目录时,他将不得不下载一个 5++ GB 的补丁。

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-09-03 22:38:13 +0000 UTC

如何确定程序集是单文件?

  • 3

在.NET Core(就像从版本 3 开始)有一个所谓的Single-file Publish,它允许您将整个项目收集到一个输出文件中,该文件还可以包含 .NET Core 本身,这允许您不将其安装在客户端上.

其实计划是让它“自动更新”,可惜不是每个人都能从网上下载“很多”,有些要么还有流量,要么速度非常低,或者其他一些问题. 而项目本身,如果使用这种技术组装起来,开始的重量不是 100kb,而是 150mb++。

为了解决这个问题,决定发表两篇文章:

  • 最小- 不包含 .NET Core 和 100kb 的重量
  • 最大- 作为 .NET Core 的一部分,重量为 100mb 及以上。

然后让客户自己决定哪种方式对他们来说更方便,他们想要什么。但!自动更新呢?您需要了解客户端的版本。

实际上是一个问题:如何定义版本的“最大”或“最小”?如何确定此 .exe 文件是否包含 .NET Core 本身?
当然,你可以尝试通过大小来确定大小,但这只是某种拐杖。您可以将信息写入文件,但对我来说,这是不对的。

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-06-26 19:17:51 +0000 UTC

HttpClient 在使用 .net 和 .net core 时给出不同的结果

  • 4

这一切的背景就在这里。

我一直在尝试解决连接微软CDN的问题一天,我什至与他们通信,但没有结果。现在我尝试在.NET Framework 上而不是在.NET Core 上制作连接文本,我有点惊讶。

有两个控制台应用程序,它们具有相同的代码:

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        private readonly static HttpClient httpClient = new HttpClient();

        static async Task Main(string[] args)
        {
            var link = "https://appcenter-filemanagement-distrib5ede6f06e.azureedge.net/a35db5eb-bf67-48be-86e9-ae7e90bb87d1/v01.zip?sv=2019-02-02&sr=c&sig=iqORygcUNXADxT8Ev6%2BrWNlPiEn%2BSakQoZM1dkgWl%2FM%3D&se=2020-06-27T09%3A49%3A04Z&sp=r";

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine($"Test [{i}]");

                foreach (SecurityProtocolType protocolType in Enum.GetValues(typeof(SecurityProtocolType)))
                {
                    Console.Write($"[{protocolType}] ");

                    try
                    {
                        ServicePointManager.SecurityProtocol = protocolType;
                        var resp = await httpClient.GetAsync(link, HttpCompletionOption.ResponseHeadersRead);
                        Console.WriteLine(resp.StatusCode);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.GetBaseException().Message);
                    }

                }

                await Task.Delay(5000);
                Console.WriteLine();
            }

            Console.WriteLine(true);
        }
    }
}

唯一的区别namespace在于,一个项目是 .NET Core,另一个是 .NET Framework。
我运行这两个项目并看到下图:

.NET Framework 在几次连接后开始思考很长时间

.NET 框架测试

我问他ServicePointManager.DefaultConnectionLimit = 15;,似乎部分解决了问题,结果是这样的:

.NET 框架测试(修复)

可以看出连接已断开,仅在极少数情况下OK可见状态。

接下来,我在 .NET Core 上运行了一个类似的测试,没有对最大连接数和其他内容进行任何设置,我看到以下内容:

.NET 核心测试

可以看到所有请求都成功完成,服务器成功返回数据,一切正常。

问题:为什么会有如此不同的结果以及如何在 .NET Framework 应用程序上实现相同的工作?为什么他完全断开连接?

该链接有自己的生命周期,在上一个问题中,您可以找到指向 API 的链接,该链接始终提供指向 CDN 的新链接。


只有我很高兴一切都通过平庸的使用解决了,这不是问题,只要我链接到我的主项目,然后再次“服务器关闭了连接”。我为测试上传了 7zip 安装程序,一个新的测试链接:

https://appcenter-filemanagement-distrib5ede6f06e.azureedge.net/c8be8012-cafe-48d4-b5e6-aab361374707/7z2000-x64.zip?sv=2019-02-02&sr=c&sig=LEGHVRXghiFi8yt4Xx%2BixNd%2BmKSbr2MfcTgtgt20= 3A31%3A08Z&sp=r

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-04-15 07:01:13 +0000 UTC

HttpClient文件下载实现

  • 6

我正在开发一个应用程序,该应用程序应将文件从网址下载到计算机,然后对其进行处理。
我完成了任务,一切正常,然后客户转向我说:

我的网速很慢,经常断线,不能直接给链接,否则程序会重新下载文件。

实际上我正在尝试解决这个问题,或者更确切地说,我需要做以下两件事:

  1. 连接断开后恢复文件下载。- 正如他们所说,在缓冲的帮助下部分解决了短期休息似乎已经消失了。
  2. 下载现有的“存根”,该存根在上一个不成功的下载过程之后仍然存在。

现在下载文件的过程如下所示:

private async Task ProcessContentStream(long? totalDownloadSize, Stream contentStream)
{
    var totalBytesRead = 0L;
    var readCount = 0L;
    var buffer = new byte[4096];
    var isMoreToRead = true;

    using (var fileStream = new FileStream(_destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
    {
        do
        {
            var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
            if (bytesRead == 0)
            {
                isMoreToRead = false;
                TriggerProgressChanged(totalDownloadSize, totalBytesRead);
                continue;
            }

            await fileStream.WriteAsync(buffer, 0, bytesRead);

            totalBytesRead += bytesRead;
            readCount += 1;

            if (readCount % 100 == 0)
                TriggerProgressChanged(totalDownloadSize, totalBytesRead);
        }
        while (isMoreToRead);
    }
}

也就是说,我们从服务器中取出一块(缓冲区)并将其写入,FileStream直到服务器为我们提供整个文件。

我试过了:

  • 在启动时,将Stream's 的位置移动到fileStream.Length(当前文件大小),但HttpClient给出通常的Stream,CanSeek = false即,我无法从某个点开始从服务器接收数据,只能从一开始。
  • 我试图跳过写入文件(await fileStream.WriteAsync(buffer, 0, bytesRead);),直到从服务器接收到的数据数量等于当前文件大小,也就是说,我做了这样的事情(草图):

    if (totalBytesRead >= fileStream.Length)
        await fileStream.WriteAsync(buffer, 0, bytesRead);
    

    但是感觉就像是因为我,await contentStream.ReadAsync(buffer, 0, buffer.Length);我仍然从服务器下载数据,但我只是不把它写下来,结果我得到了一个损坏的文件,在下载停止的地方正好有一个间隙。在这里,很可能发生这种情况是因为当应用程序关闭和重新加载时缓冲区没有完全写入,我需要更早地开始写入文件 1“缓冲区”,但我不明白如何执行此操作。

简而言之,在应用程序中断/关闭后,我陷入了僵局,不知道如何恢复磁盘上的现有文件。如果你教我从服务器的某个位置获取字节而不影响开头(Seekin Stream),那就太好了,那么你可以在休息后请求这些字节并继续下载,或者还有其他选择吗?

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-03-25 23:36:13 +0000 UTC

合并两个目录的虚拟文件系统

  • 0

有一个应用程序(不是我写的,也没有访问权限),可以通过各种修改来扩展,只需将.dll 文件放在主.exe 旁边即可。

随着时间的推移,这个项目积累了很多这样的扩展,主目录变成了一个转储,很难找到原始文件和扩展文件。

现在我决定克服这个问题并将修改与主应用程序分开,将它们放在一个单独的目录中,但问题是 - 我无法重写项目,它不会注册来自另一个目录的修改。我想在“符号链接”(及其类似物)的帮助下解决这个问题,但我陷入了一种死胡同,我必须使用这些链接手动注册很多文件,如果有任何添加/删除,然后再次手动创建一个新链接。此外,为了借助链接解决这个问题,我必须将所有内容重定向到一个目录,这将是一种文件转储并从那里启动项目,你看,这不是一个非常方便的解决方案......

这一切想了很久,我记得很久以前我看到一个项目,它可以让你从游戏中断开配置文件、设置、修改和其他所有内容,并且做得非常优雅,将所有内容保存在一个游戏目录中. 那个项目被Mod Organizer称为。在研究了这个程序的特点之后,我意识到他们使用了所谓的“虚拟文件系统”/VFS(虚拟文件系统),这就是我对主 OS 文件系统上的一些抽象层的理解,它一劳永逸会让我做我想做的事。

寻找至少一个简单的实现,我遇到了像Zio这样的库,它似乎能够做到这一点,但无论我如何扭曲它们,结果都是零,我什至不能简单地将两个真实目录连接到1个虚拟的,我说的是运行程序我沉默..

问题:伙计们,走在正确的道路上,帮助实现 VFS,它将两个目录合并为 1 并启动项目。

目录示例:

  • 前:

    /App/Application.exe
    /App/SomeMod.dll
    /App/SomeMod2.dll

  • 后:

    /App/Application.exe
    /Modifications/SomeMod.dll
    /Modifications/SomeMod2.dll

运行时,/App/Application.exe程序会在 中找到所有内容Modifications,注册它们并成功运行。

c#
  • 2 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-02-10 06:00:20 +0000 UTC

根据 MVVM 规则在 WPF 中的 IoC

  • 2

渐渐地,我开始研究 IoC 和所有这些美食,现在我只是想不通如何根据 MVVM 的规则在 WPF 应用程序中使用它们。

假设我做了一些容器设置(我使用 Autofac):

class ContainerConfig
{
    public static IContainer Configure()
    {
        ISettings settings = new ConfigurationBuilder<ISettings>().UseJsonFile("Settings.json").Build();
        var builder = new ContainerBuilder();

        builder.RegisterType<MainViewModel>().SingleInstance();
        builder.RegisterInstance(settings).SingleInstance();

        return builder.Build();
    }
}

到目前为止,我在其中注册了 2 个对象:

  1. MainViewModel- 应用程序的主虚拟机,据我了解,它应该在一个实例中。
  2. 一些应用程序设置对象。

接下来,我覆盖OnStartup,为了创建一个窗口,设置它DataContext并显示所有这些:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        var container = ContainerConfig.Configure();
        using var scope = container.BeginLifetimeScope();
        var mainViewModel = scope.Resolve<MainViewModel>();
        new MainWindow() { DataContext = mainViewModel }.Show();
    }
}

看来,当我朝着正确的方向前进时,或者不是?
好的,接下来要测试工​​作,我将通过写入MainViewModel以下内容来简单地绑定设置中的属性:

class MainViewModel
{
    public ISettings Settings { get; }

    public MainViewModel(ISettings settingsModel)
    {
        Settings = settingsModel;
    }
}

以及绑定本身:

<TextBlock Text="{Binding Settings.SomeValue}"/>

一切似乎都正常,一切都很好。
现在假设我需要创建另一个 VM,例如,它需要一个主 VM,我这样做:

class SecondViewModel
{
    private MainViewModel main;
    public SecondViewModel(MainViewModel mainViewModel)
    {
        main = mainViewModel;
    }

    public int Test { get; set; } = 33;

    private void SomeMethod()
    {
        main.SomeProperty = false;
    }
}

我注册它:

builder.RegisterType<SecondViewModel>().SingleInstance();

好吧,我添加到MainViewModel新的虚拟机:

class MainViewModel
{
    public ISettings Settings { get; }
    public SecondViewModel Second { get; }

    public MainViewModel(ISettings settingsModel, SecondViewModel second)
    {
        Settings = settingsModel;
        Second = second;
    }
}

结果,我得到一个循环错误,然后我清楚地明白我做错了什么。
在搜索了一些信息后,我找到了一种解决方法。

简而言之,正如您所看到的,我不太了解这一切应该如何工作,并且出现了很多问题,例如:

  1. 我做对了吗?
  2. 容器中应该记录什么?
  3. VM 层是否需要接口?
  4. 如何不破坏 MVVM?

一般来说,帮助我弄清楚如何在 WPF 应用程序中正确实现 IoC,甚至使用 MVVM?

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-07-14 22:26:57 +0000 UTC

从 CDN 加载图像时出现问题:文件到达时小于预期

  • 1

有一个图像:https://media.alienwarearena.com/images/content/rank-insignias/lg/10.png
我尝试用<Image/>( <Image Source="адрес">) 显示它,结果我得到一个空窗口。

我想,好吧,我会尝试下载它,我写道:

var imgUrl = new Uri("https://media.alienwarearena.com/images/content/rank-insignias/lg/10.png");
var client = new WebClient();
client.DownloadFile(imgUrl, "10.png");

结果是一个重 14kb(28kb 原始)的损坏图像。
我尝试添加不同的标题(下图中的所有内容),但没有任何意义。

通过普通浏览器请求:

标题

也许有人知道是什么阻止了这个地址的工作?

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-08-11 05:22:45 +0000 UTC

WebClient 文件下载部分的大小

  • 1

有一项任务是从带有进度显示(总和当前文件大小)的 Web 服务器下载约 3000 个文件。也就是为了方便用户,需要实现文件的总大小和总共下载多少(例如:100mb out of 300mb download)。

我从服务器以 JSON 数据的形式获取上传文件的总大小(它提供了一个列表,其中包含有关每个文件、其大小、名称等的信息),但当前大小存在困难......

我使用WebClinet,我从中捕获事件DownloadProgressChanged。在这个事件里面,我们可以得到BytesReceived,也就是我们已经从这个文件下载了多少的大小,它一直在增长,直到它变成 = 文件的完整大小。

我的任务是计算在一次事件调用中下载了多少字节DownloadProgressChanged,而不是总数。我试图将前一个保存在一个BytesReceived单独的变量中( 11561291193(也就是差不多一半,但是所有文件都接收成功!计数不正确...)。oldSizevar size = e.BytesReceived - oldSize;

请帮助我实现从服务器下载的字节的有效输出......


当前实施:

private void RepairClient()
{
    var filesBlock = new BufferBlock<FileViewModel>();
    var generateOptions = new ExecutionDataflowBlockOptions
    {
        MaxDegreeOfParallelism = 4,
        BoundedCapacity = 100
    };

    var downloadBlock = new ActionBlock<FileViewModel>(async file =>
    {
        SetFileName(file.Name);
        var packPach = file.Name + ServerData.PackName;
        var uri = new Uri(main.UpdaterViewModel.Path, packPach);
        var fullPackPach = Model.StorageModel.ExpandRelativeName(packPach);
        await file.DownloadFile(uri, fullPackPach, main);
    }, generateOptions);


    var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
    filesBlock.LinkTo(downloadBlock, linkOptions);

    var totalSize = UpdateFiles.Sum(x => x.FileSize);

    SetMinMax(0, UpdateFiles.Count);
    SetSize(total: totalSize); //Вывести в интерфейс полный размер.
    SetMinMax(0, totalSize); //Работа с ProgressBar (задать min и max).
    SetStatus(true);

    UpdateFiles.ForEach(x => filesBlock.Post(x));
    filesBlock.Complete();
    downloadBlock.Completion.Wait();
}

我尝试使用简单的方法编写方法acync,现在我正在玩Dataflow,但无济于事。在 blockdownloadBlock中,我们做通常的准备(我们计算路径)并调用DownloadFile当前文件的方法。

方法DownloadFile:

public async Task DownloadFile(Uri uri, string path, MainViewModel main)
{
    try
    {
        using (var client = new WebClient())
        {
            long prev = 0;
            client.DownloadProgressChanged += (sender, args) =>
            {
                var diff = args.BytesReceived - prev;
                main.Progress.Size += diff;
                prev = args.BytesReceived;

                Console.WriteLine($"[{path}]: BytesReceived: {args.BytesReceived} (diff: {diff})");
            };

            var dir = Path.GetDirectoryName(path);
            if (dir != null && !Directory.Exists(dir)) Directory.CreateDirectory(dir);

            await client.DownloadFileTaskAsync(uri, path);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
}

这是结果的输出:

[patchw32.dll.client]: BytesReceived: 10215 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 3370 (diff: -2738)
[patchw32.dll.client]: BytesReceived: 11584 (diff: 9583)
[patchw32.dll.client]: BytesReceived: 2001 (diff: 2001)
[patchw32.dll.client]: BytesReceived: 6108 (diff: 6108)
[patchw32.dll.client]: BytesReceived: 8846 (diff: 8846)
[patchw32.dll.client]: BytesReceived: 4739 (diff: -6845)
[patchw32.dll.client]: BytesReceived: 12953 (diff: 8214)
[patchw32.dll.client]: BytesReceived: 7477 (diff: -5476)
[patchw32.dll.client]: BytesReceived: 14322 (diff: 6845)
[patchw32.dll.client]: BytesReceived: 15691 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 17060 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 18429 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 19798 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 21167 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 22536 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 23905 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 25274 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 26643 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 28012 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 29381 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 30750 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 32031 (diff: 1281)
[patchw32.dll.client]: BytesReceived: 33400 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 34769 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 36138 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 37507 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 38876 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 40245 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 41614 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 42983 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 44352 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 45721 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 47090 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 48459 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 49828 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 51197 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 52566 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 53935 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 55304 (diff: 1369)
[patchw32.dll.client]: BytesReceived: 59533 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 63762 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 64799 (diff: 1037)
[patchw32.dll.client]: BytesReceived: 69028 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 73257 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 77486 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 81715 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 85944 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 90173 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 94402 (diff: 4229)
[patchw32.dll.client]: BytesReceived: 95819 (diff: 1417)
[patchw32.dll.client]: BytesReceived: 95819 (diff: 0)
[L2text\help_battle_shot.htm.client]: BytesReceived: 1067 (diff: 1067)
[L2text\help_battle_shot.htm.client]: BytesReceived: 1067 (diff: 1067)
[L2text\help_item_symbol.htm.client]: BytesReceived: 936 (diff: 936)
[L2text\help_item_symbol.htm.client]: BytesReceived: 936 (diff: 936)
[L2text\help_option_video.htm.client]: BytesReceived: 2337 (diff: 2337)
[L2text\help_option_video.htm.client]: BytesReceived: 2337 (diff: 2337)
[L2text\credit_us_03.htm.client]: BytesReceived: 907 (diff: 907)
[L2text\credit_us_03.htm.client]: BytesReceived: 907 (diff: 907)
[L2text\pet_help_quest_2.htm.client]: BytesReceived: 809 (diff: 809)
[L2text\pet_help_quest_2.htm.client]: BytesReceived: 809 (diff: 809)
[music\S09_F.ogg.client]: BytesReceived: 1992 (diff: 1992)
[music\S09_F.ogg.client]: BytesReceived: 3361 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 4730 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 6099 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 10206 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 11575 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 7468 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 8837 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 14313 (diff: 2738)
[music\S09_F.ogg.client]: BytesReceived: 12944 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 15682 (diff: 2738)
[music\S09_F.ogg.client]: BytesReceived: 17051 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 18420 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 19789 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 21158 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 22527 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 23896 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 25265 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 26634 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 28003 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 29372 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 30741 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 31384 (diff: 643)
[music\S09_F.ogg.client]: BytesReceived: 32753 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 34122 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 35491 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 36860 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 38229 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 39598 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 40967 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 42336 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 43705 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 45074 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 46443 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 47812 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 49181 (diff: 1369)
[music\S09_F.ogg.client]: BytesReceived: 53410 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 57639 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 61868 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 64152 (diff: 2284)
[music\S09_F.ogg.client]: BytesReceived: 68381 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 72610 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 76839 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 81068 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 85297 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 89526 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 93755 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 96920 (diff: 3165)
[music\S09_F.ogg.client]: BytesReceived: 101149 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 105378 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 109607 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 113836 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 118065 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 122294 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 126523 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 129688 (diff: 3165)
[music\S09_F.ogg.client]: BytesReceived: 133917 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 138146 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 142375 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 146604 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 150833 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 155062 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 159291 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 162456 (diff: 3165)
[music\S09_F.ogg.client]: BytesReceived: 166685 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 170914 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 175143 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 179372 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 183601 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 187830 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 192059 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 195224 (diff: 3165)
[music\S09_F.ogg.client]: BytesReceived: 199453 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 203682 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 207911 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 212140 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 227992 (diff: 15852)
[music\S09_F.ogg.client]: BytesReceived: 244376 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 260760 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 277144 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 293528 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 309912 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 326296 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 342680 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 359064 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 375448 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 3483 (diff: 3483)
[music\sc08_f.ogg.client]: BytesReceived: 7712 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 11941 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 16170 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 20399 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 24628 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 28857 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 31383 (diff: 2526)
[music\S09_F.ogg.client]: BytesReceived: 391832 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 35612 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 39841 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 44070 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 48299 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 408216 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 52528 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 56757 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 60986 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 64151 (diff: 3165)
[music\sc08_f.ogg.client]: BytesReceived: 68380 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 72609 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 76838 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 81067 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 424600 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 440984 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 85296 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 89525 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 93754 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 96919 (diff: 3165)
[music\sc08_f.ogg.client]: BytesReceived: 101148 (diff: 4229)
[music\sc08_f.ogg.client]: BytesReceived: 105377 (diff: 4229)
[music\S09_F.ogg.client]: BytesReceived: 457368 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 473752 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 121761 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 129687 (diff: 7926)
[music\S09_F.ogg.client]: BytesReceived: 490136 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 146071 (diff: 16384)
[music\S09_F.ogg.client]: BytesReceived: 501222 (diff: 11086)
[music\S09_F.ogg.client]: BytesReceived: 501222 (diff: 0)
[music\sc08_f.ogg.client]: BytesReceived: 162455 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 178839 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 195223 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 211607 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 227991 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 244375 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 260759 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 277143 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 293527 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 309911 (diff: 16384)
[music\sc08_f.ogg.client]: BytesReceived: 313342 (diff: 3431)
[music\sc08_f.ogg.client]: BytesReceived: 313342 (diff: 0)
[music\SSQ05_F.ogg.client]: BytesReceived: 15638 (diff: 15638)
[music\SSQ05_F.ogg.client]: BytesReceived: 32022 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 48406 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 64790 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 81174 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 97558 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 113942 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 130326 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 146710 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 162459 (diff: 15749)
[music\SSQ05_F.ogg.client]: BytesReceived: 178843 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 195227 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 211611 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 227995 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 244379 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 260763 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 277147 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 293531 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 309915 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 326299 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 342683 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 359067 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 375451 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 391835 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 408219 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 424603 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 440987 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 457371 (diff: 16384)
[music\SSQ05_F.ogg.client]: BytesReceived: 469073 (diff: 11702)
[music\SSQ05_F.ogg.client]: BytesReceived: 469073 (diff: 11702)
[StaticMeshes\Aden_castle_door_S.usx.client]: BytesReceived: 3614 (diff: 3614)
[StaticMeshes\Aden_castle_door_S.usx.client]: BytesReceived: 3614 (diff: 3614)

您可能会注意到 Diff 并不总是达到 0,有时甚至会变为负数……

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-07-15 18:34:01 +0000 UTC

搜索整个 JSON 文件

  • 1

有一个JSON具有类似结构的小文件(约 400 行):

{
  "Items": [
    {
      "type": "Тип 1",
      "Ключ1": "Значение 1",
      "Ключ2": "Значение 2"
    },
    {
      "type": "Тип 2",
      "Ключ3": "Значение 3",
      "Ключ4": "Значение 4"
    }
  ]
}

该文件显然分为多个部分,其中第一个值始终是type- 该值表示类别的名称。此外,在每个类别中都有一个值(这里我将其指定为键)——它是唯一的。

问题是,我如何搜索整个文件Ключ- 获取它Значение和其中的当前“类别” type?

目前,我正在逐行加载整个文件,并在生成的数组中寻找具有所需键的行。接下来,我反序列化该值并提取该值。这个选项很好用,但我不能得到type,而且这个选项本身看起来像一个“拐杖”。


为了更好的理解,举个例子:

例如,我们有“Key3”——我们进行搜索——在输出中我们得到“Value 3”和“Type 2”。

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-07-12 03:55:05 +0000 UTC

如何缩短或完全消除此类代码?

  • 1

我有许多按钮可以切换应用程序页面。按钮有 2 种状态,按下和未按下,每种状态都实现了一种样式Menu- 正常和MenuIn- 按下(也就是说,此页面当前为用户打开)。样式只会改变颜色。

现在我将每个按钮都附加到一个处理程序,它使用switch按钮名称执行必要的操作,即打开所需的页面,为所有非活动按钮Menu设置样式,并为当前部分的按钮设置样式MenuIn。结果,我得到了一大块重复线条的鞋垫。

如何正确缩短代码,它能以某种方式确定按钮是否被按下的样式,也许是别的什么?


private void ButtonEvent(string name)
        {
            switch (name)
            {
                case "ChangeBg":
                    BackgroundEvent.Restart();
                    break;
                case "HomeBtn":
                    HomeBtn.Style = (Style) Application.Current.Resources["MenuIn"];
                    NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
                    TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    MainFrame.Navigate(new Uri("View/HomePage.xaml", UriKind.Relative));
                    break;
                case "NewsBtn":
                    HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    NewsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
                    AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
                    TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    //MyPopup.IsOpen = true;
                    MainFrame.Navigate(new Uri("View/NewsPage.xaml", UriKind.Relative));
                    break;
                case "AlertsBtn":
                    HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    AlertsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
                    InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
                    TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    //MyPopup.IsOpen = false;
                    //BodyFrame.Navigate(new Uri("Pages/AlertsPage.xaml", UriKind.Relative));
                    break;
                case "TradeBtn":
                    HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
                    TradeBtn.Style = (Style) Application.Current.Resources["MenuIn"];
                    ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    //BodyFrame.Navigate(new Uri("Pages/TradePage.xaml", UriKind.Relative));
                    break;
                case "InvasionsBtn":
                    HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InvasionsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
                    SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
                    TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    //BodyFrame.Navigate(new Uri("Pages/InvasionsPage.xaml", UriKind.Relative));
                    break;
                case "InfoBtn":
                    HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InfoBtn.Style = (Style) Application.Current.Resources["MenuIn"];
                    TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    //BodyFrame.Navigate(new Uri("Pages/InfoPage.xaml", UriKind.Relative));
                    break;
                case "SettingsBtn":
                    HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
                    SettingsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
                    TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    //BodyFrame.Navigate(new Uri("Pages/SettingsPage.xaml", UriKind.Relative));
                    break;
                case "ActMissionsBtn":
                    HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
                    SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
                    TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
                    ActMissionsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
                    //BodyFrame.Navigate(new Uri("Pages/ActiveMissionsPage.xaml", UriKind.Relative));
                    break;
            }
        }

在此处输入图像描述

c#
  • 3 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-07-02 01:08:33 +0000 UTC

验证消息的翻译

  • 0

我正在 Asp.Net Core 上创建一个站点,它有一个注册和一个反馈表。验证在表单中设置(是否填写字段、字符数等)。

表格没有问题,一切正常,但运气不好 - 验证消息以英文发出。

求助,如何翻译这些信息?

验证是如何实现的

翻译繁琐的图(红字): 在此处输入图像描述

asp.net-core
  • 3 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-05-09 22:37:40 +0000 UTC

当一个独特的元素被添加到 ViewModel 时帮助实现 Event 事件

  • 2

先生们,告诉我如何创建一个事件 ( Event),您可以ViewModel使用已实现的INotifyPropertyChanged?

最近问了一个问题,是哪里帮我实现了一个界面更新INotifyPropertyChanged,项目工作如下:

  • 事件,每 N 秒一次,从服务器本地加载 JSON 文件。
  • 此外,该操作由签名事件执行Load();,它将所有这些 JSON 加载到ViewModel.
  • 嗯,通过一个简单的Binding值被显示在ListBox.

问题本身(带有必要的代码和指向 GitHub 的链接)可以在这个链接中查看。

实际上,现在您需要尝试执行检查以将唯一元素添加到集合中Alerts并将其用于事件(借助该检查,稍后将显示有关新游戏事件的通知)。此外,使用此事件,您需要获取集合中此唯一元素的数据(用于在通知时详细输出信息,以及将这些事件的历史记录写入文件)。


还有一个关于绑定的问题:How to bind stringa value to a normal one Lablewith a DataContentwindow -bound value ViewModel?

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-05-08 00:42:40 +0000 UTC

帮助实现WPF中的数据刷新

  • 3

先生们,请帮助实施数据的主管更新。

应用操作:

  • 该事件会定期下载一个 JSON 文件。
  • 我们使用事件的签名方法来读取Load();这个文件并将所有数据输入到某个模型中。
  • 我们进行数据绑定和输出。

目前我有这样一个“拐杖”(删除旧的数据绑定并用新的绑定它):

 if (alertbox.ItemsSource != null) alertbox.ItemsSource = null;
 alertbox.ItemsSource = News.Data.Posts;

你真的需要摆脱它。我尝试实施INotifyPropertyChanged,但无论我做什么,数据仍然很旧......


实际上代码本身:

从 JSON 文件加载数据(主要方法Read和静态方法方便Load):

internal class Game
{
    private static GameView Read(string fileName)
    {
        GameView data;
        using (var file = File.OpenText(fileName))
        {
            var serializer = new JsonSerializer();
            data = (GameView) serializer.Deserialize(file, typeof(GameView));
        }

        return data;
    }

    /// <summary>
    ///     Основные игровые данные.
    /// </summary>
    public static GameView Data;

    /// <summary>
    ///     Загружаем JSON файл с игровыми данными.
    /// </summary>
    /// <param name="filename">Путь до JSON файла</param>
    public static void Load(string filename = "temp")
    {
        if (filename == "temp") filename = $"{Settings.Program.Directories.Temp}/GameData.json";
        Data = Read(filename);
    }
}

型号GameView:

public class GameView
{
    public int Version { get; set; }
    public string MobileVersion { get; set; }
    public string BuildLabel { get; set; }
    public int Time { get; set; }
    public int Date { get; set; }
    public List<Alert> Alerts { get; set; }
    public List<double> ProjectPct { get; set; }
    public string WorldSeed { get; set; }
}

public class Alert
{
    [JsonProperty("_id")]
    public Id Id { get; set; }
    public Activation Activation { get; set; }
    public Expiry Expiry { get; set; }
    public MissionInfo MissionInfo { get; set; }
}

public class MissionInfo
{
    public string MissionType { get; set; }
    public string Faction { get; set; }
    public string Location { get; set; }
    public string LevelOverride { get; set; }
    public string EnemySpec { get; set; }
    public int MinEnemyLevel { get; set; }
    public int MaxEnemyLevel { get; set; }
    public double Difficulty { get; set; }
    public int Seed { get; set; }
    public int MaxWaveNum { get; set; }
    public MissionReward MissionReward { get; set; }
    public string ExtraEnemySpec { get; set; }
    public List<string> CustomAdvancedSpawners { get; set; }
    public bool? ArchwingRequired { get; set; }
    public bool? IsSharkwingMission { get; set; }
}

我怎么打电话:

Game.Load();
alertbox.ItemsSource = Game.Data.Alerts;

嗯,目前最简单的ListBox:

<ListBox x:Name="alertbox" Background="{x:Null}" BorderBrush="{x:Null}">
                    <ListBox.ItemTemplate>
                        <DataTemplate >
                            <Label Content="{Binding MissionInfo.Location}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

在这种情况下帮助实现对在加载 JSON 文件后立即更新界面中的数据的支持。整个项目上传到GitHub

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-05-03 06:46:30 +0000 UTC

$ 变量名中的符号

  • 3

我想读取一个JSON文件,但是出现了一个问题:文件中的某些名称在名称中包含一个字符$,导致出现“Invalid character in the name”的错误

告诉我在这种情况下该怎么办?

我用Newtonsoft.Json。

文件的一部分:

$date: {
   $numberLong: "1493325863000"
}

PS:我不想写类似的东西obj["$date"]。

c#
  • 1 个回答
  • 10 Views
Martin Hope
EvgeniyZ
Asked: 2020-09-20 01:57:15 +0000 UTC

如果选择了第二个列表框中的另一个项目,则重置选择

  • 1

我有一个 WPF 应用程序,它有两个ListBox. 我需要这样做,以便当您在其中一个中选择一个元素时,另一个中ListBox的选择被重置,反之亦然。

我试图在每个事件上SelectionChanged和其中挂起一个事件SelectedIndex = -1,但结果很疯狂,因为事件(当然)对两个ListBox-s 都有效,这导致两者的选择都被取消(之后我不得不重新 -选择)

总的来说,我请求您帮助解决这个问题!

c#
  • 2 个回答
  • 10 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5