c# - 基于 ViewModel 状态显示 UI 错误消息的最佳实践

标签 c# wpf mvvm localization

关闭。这个问题是opinion-based .它目前不接受答案。












想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它.

5年前关闭。




Improve this question




我有一个 WPF 应用程序,如果 ViewModel 状态指示发生错误,我想在其中显示“友好”和详细的错误描述。所以,作为一个非常简单的第一遍,我有:

XAML

<Label>
  <TextBlock TextWrapping="WrapWithOverflow" Text="{Binding Path=ErrorMessage}" />
</Label>

View 模型
public string ErrorMessage { get; set; }

private void DoSomething()
{
    try { /* ... */ }
    catch (Exception1) { ErrorMessage = "Long description 1"; }
    catch (Exception2) { ErrorMessage = "Long description 2"; }
    catch (Exception3) { ErrorMessage = "Long description 3"; }
}

(注意,PropertyChanged.Fody 用于自动实现上述 ViewModel 属性的 INotifyPropertyChangedDoSomething() 通过 RelayCommand 触发。)

这工作得很好,但我当然不希望 ViewModel 代码中有那些长描述字符串。所以我开始阅读 WPF 本地化,ResourceDictionary等等,我很快就完全迷路了。

在我看来,如果我能做这样的事情,那将是非常理想的:

XAML(假设)
<Label>
  <TextBlock TextWrapping="WrapWithOverflow" Text="{Binding Path=Error, Converter?=???}" />
</Label>

View 模型(假设)
public enum Errors { None, Error1, Error2, Error3 };
public Errors Error get; set; }

private void DoSomething()
{
    try { /* ... */ }
    catch (Exception1) { Error = Errors.Error1; }
    catch (Exception2) { Error = Errors.Error2; }
    catch (Exception3) { Error = Errors.Error3; }
}

某处? (完全假设)
<Strings>
    <String Key="MyViewModel.Errors.Error1">
        Long description 1
    </String>
    <!-- etc. -->
</Strings>

现在,以上内容完全是虚构的,根据我所读到的内容,我认为 ResourceDictionary可能是存储字符串的地方。但我不知道如何将字符串与可能的错误条件的枚举相关联。当然它不一定是 enum要么 -- 我可以在 Error 中存储一个字符串键或其他东西领域——这对我来说是最理想的。

我知道我可以将字符串资源放入 ResourceDictionary然后使用 Application.Current.Resources在 ViewModel 代码中查找字符串并使用它来填充 ErrorMessage .但我认为那会很糟糕 - ViewModel 不应该知道或关心实际的消息文本,这是 View 关注的问题。所以在我看来,View 应该根据 ViewModel 状态找出合适的字符串来呈现。

理想情况下,该字符串将来也应该是可本地化的,尽管我目前还没有本地化应用程序(我对 WPF 本地化还不够了解,而且这个应用程序不需要它)。

问题是,您能否指出关于 WPF 最佳实践的正确方向,以显示上述示例中的键控消息? 我不介意跑腿来学习我需要学习的东西,但是当我在网上阅读这篇文章时,我很快就完全迷失了,只需要一点指导。谢谢!

最佳答案

View 模型使用 TextBlock 元素公开 View 绑定(bind)到的字符串值是非常好的和非常常见的。如果您不想将字符串值硬编码到 View 模型类中,则可以将字符串存储在单独的类中:

查看型号:

private void DoSomething()
{
    try { /* ... */ }
    catch (Exception1) { ErrorMessage = StringResources.ErrorMessageA; }
    catch (Exception2) { ErrorMessage = StringResources.ErrorMessageB; }
}

StringResources.cs:
public static class StringResources
{
    public const string ErrorMessageA = "...";
    public const string ErrorMessagB = "...";
}

如果您出于某种原因不喜欢这个,您仍然可以从 View 模型中公开诸如“Error1”和“Error2”之类的键,然后使用转换器或自定义标记扩展将它们转换为 View 中的实际字符串值。请参阅以下链接以获取更多信息:

https://www.codeproject.com/articles/35159/wpf-localization-using-resx-files

https://wpftutorial.net/LocalizeMarkupExtension.html

Recommendation on a XAML RESX markup extension

关于c# - 基于 ViewModel 状态显示 UI 错误消息的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42074078/

相关文章:

c# - WPF 组合框不更新 ViewModel

wpf - Setter 不在依赖属性上运行?

c# - 使用 TwoWay 绑定(bind)到带有 IValueConverter 的 ItemsSource

wpf - 为什么我不能在 Rectangle.Width 上使用 IMultiValueConverter?

c# - MultiBinding 与多个输出

C#取消一个非循环的长时间运行的任务

c# - 与 ASPNET Core 和 websockets 的双向通信

c# - 通用表单的具体实现在设计器中不起作用

.net - 如何为 >= Vista 自定义 FileOpen 对话框?

c# - 将 Windows WPF 桌面应用程序移动到 Windows 应用商店应用程序有哪些以触摸为中心的开发优势?