1
0
Files
BallanceTasToolbox/BallanceTasEditor/ViewModels/NewFileDialog.cs

86 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BallanceTasEditor.Utils;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.ViewModels {
public struct NewFileDialogResult {
public int Count { get; set; }
public float DeltaTime { get; set; }
}
public partial class NewFileDialog : ObservableValidator {
public NewFileDialog() {
Count = 10000.ToString();
// 132 or 264
Fps = 264.ToString();
}
// YYC MARK:
// 经过无数次的尝试我发现将int类型绑定到TextBox中所需要涉及的事情太多了
// 尤其是这种绑定到处存在于这个程序中,以至于每次都要重新写一遍。
// 也许后面我会做一个只能接受数字输入的文本框,但现在我累了。
//
// 具体来说事情是这样的。我一开始就是使用一个int类型的数据
// 然后按照CommunityToolkit.Mvvm的标准将其应用了Required和Range Attribute然后将其绑定到了TextBox的Text之上。
// 然而最终的效果很奇怪当我删除TextBox中的所有字符后绑定什么也没做后来我才知道要在Required里改一个选项
// 其次当我输入不被Range接受的数值时它仍会将其同步绑定到属性上。比如我输入0它仍会将其绑定到Fps上
// 进而导致Delta Time的转换显示抛出除以零的错误。这些都不是我想要的。
// 同时,这样做的话,我没有办法检测这些字段到底是不是合规的。
//
// 然后我就将int改写为了int?类型用null表示当前值不可接受非null表示绑定的值。
// 然后定义了一个转换器负责在int?和string之间进行转换并同时去除了所有的验证性Attribute
// 然而遗憾的是,这么做也不符合我的要求。当我尝试输入一个数值的时候,如果我输入了任何无效值,
// 那么转换器会将其转换为null值同时将该值赋给Fps而被赋值的Fps又反向传播把这个null传递给了转换器
// 转换器将其转换成为空白值,并显示在界面上。这么做的视觉效果就是一旦我输入无效值,整个文本框就会被清空,非常的反人类。
// 而且这一问题是不可调和的我不能在接收到null时选择不更新文本框的值因为有可能这个null是我手动放进去的而不是从转换器接受的。
//
// 所以最终我想通了我决定抛弃将int和TextBox.Text绑定在一起的想法。
// 就直接把string绑定到TextBox.Text上然后再辅以我自己定义的一套可复用验证逻辑。
[ObservableProperty]
[CustomValidation(typeof(NewFileDialog), nameof(ValidateCount))]
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
private string count;
[ObservableProperty]
[CustomValidation(typeof(NewFileDialog), nameof(ValidateFps))]
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
private string fps;
public static ValidationResult ValidateCount(string count, ValidationContext context) {
return CountValidator.Instance.Validate(count);
}
public static ValidationResult ValidateFps(string fps, ValidationContext context) {
return FpsValidator.Instance.Validate(fps);
}
[RelayCommand(CanExecute = nameof(CanOk))]
private void Ok() {
}
private bool CanOk() {
return !HasErrors;
}
[RelayCommand]
private void Cancel() {
}
public NewFileDialogResult ToResult() {
return new NewFileDialogResult {
Count = CountValidator.Instance.Fetch(Count),
DeltaTime = FpsConverter.ToDelta(FpsValidator.Instance.Fetch(Fps)),
};
}
}
}