WPF DataBinding 监视抛出的异常

2024-01-01

在我的模型中,我有很多不同对象的属性,我在设置对象值时检查该值,如果该值不被接受,我将抛出一个异常,这与 Windows 窗体 propertygrid 完美配合,但现在我正在尝试使用 WPF 设计新界面。 在WPF中,当我将属性绑定到文本框之类的控件时,当值更改时我不知道如何处理异常并显示错误消息。 例子 :

public string  ConnectionString
        {
            get
            {
                return (_ConnectionString);
            }
            set
            {
                try
                {
                    _ConnectionString  = value ;
                    _SqlConnection = new System.Data.SqlClient.SqlConnection(_ConnectionString);
                    _ConnectionTested = true;
                }
                catch (Exception caught)
                {
                    _ConnectionTested = false;
                    _TableNameTested = false;
                    _FieldNameTested = false;
                    _ConditionTested = false;
                    _ConnectionString = "";
                    //----delete values----
                    ValuesCollection.Clear();
                    throw (new Exception("Can not Open the connection String \nReason : " + caught.Message )); 
                }
            }
        }

wpf 部分如下:

<TextBox TextWrapping="Wrap" x:Name="ConnectionStringTextBox" Text="{Binding Path=ConnectionString, Mode=TwoWay}"/>

无论如何,当文本框中的值发生更改时,检查模型是否引发异常,然后向用户显示异常消息?

thanks


Kent 关于使用 ValidationRule 和 ExceptionValidationRule 的说法绝对正确。然而,您会发现这个解决方案非常不适合您的情况,因为您有很多这样的字段绑定。在许多地方,您将替换如下内容:

<TextBox Text="{Binding Value}" />

有了这个:

<TextBox Validation.ErrorTemplate="{StaticResource errorTemplate}">
  <TextBox.Text>
    <Binding Path="Value">
      <Binding.ValidationRules>
        <ExceptionValidationRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

因为这太笨拙了,所以我喜欢创建一个继承的附加属性来自动应用验证规则,所以我要说的是:

<Window
  ValidationHelper.ErrorTemplate="{StaticResource errorTemplate}"
...
   <TextBox Text="{Binding Value}" />
   <TextBox Text="{Binding OtherValue}" />

我的附加属性自动将验证应用于窗口中的每个绑定,因此各个文本框不必担心验证。

为此,我使用以下通用技术:

  public class ValidationHelper : DependencyObject
  {
    [ThreadStatic]
    static List<DependencyObject> _objectsNeedingValidationUpdate;

    public static ControlTemplate GetErrorTemplate(DependencyObject obj) { return (ControlTemplate)obj.GetValue(ErrorTemplateProperty); }
    public static void SetErrorTemplate(DependencyObject obj, ControlTemplate value) { obj.SetValue(ErrorTemplateProperty, value); }
    public static readonly DependencyProperty ErrorTemplateProperty = DependencyProperty.RegisterAttached("ErrorTemplate", typeof(ControlTemplate), typeof(ValidationHelper), new FrameworkPropertyMetadata
    {
      Inherits = true,
      PropertyChangedCallback = (obj, e) =>
        {
          if(e.NewValue)
            if(_objectsNeedingValidationUpdate!=null)
              _objectsNeedingValidationUpdate.Add(obj);
            else
            {
              _objectsNeedingValidationUpdate = new List<DependencyObject>();
              _objectsNeedingValidationUpdate.Add(obj);
              Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new Action(UpdateValidations));
            }
        },
    });

    static void UpdateValidations()
    {
      List<DependencyObject> objects = _objectsNeedingValidationUpdate;
      _objectsNeedingValidationUpdate = null;
      if(objects!=null)
        foreach(DependencyObject obj in objects)
          UpdateValidations(obj);
    }
    static void UpdateValidations(DependencyObject obj)
    {
      // My regular code uses obj.GetLocalValueEnumerator here, but that would require some other complexity
      if(UpdateValidations(obj, TextBox.TextProperty))
        if(Validation.GetErrorTemplate(obj)==null)
          Validation.SetErrorTemplate(obj, ValidationHelper.GetErrorTemplate(obj));
    }
    static bool UpdateValidations(DependencyObject obj, DependencyProperty prop)
    {
      var binding = BindingOperations.GetBinding(obj, prop);
      if(binding!=null &&
        binding.Mode==BindingMode.TwoWay &&
        !binding.ValidationRules.Any(rule => rule is ExceptionValidationRule))
      {
        binding.ValidationRules.Add(new ExceptionValidationRule());
        BindingOperations.SetBinding(obj, prop, binding);  // Required to get new rule to work
        return true;
      }
      return false;
    }
  }

有关如何创建 errorTemplate 资源的示例,请参阅 Validation 类的 MSDN 文档。另请注意:

  • 我的 ValidationHelper 类不会阻止您设置自定义 Validation.ErrorTemplate 值 单独的文本框。这些将覆盖 ValidationHelper.ErrorTemplate。
  • 您可以轻松添加对 TextBox 以外的控件和 Text 以外的属性的支持
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF DataBinding 监视抛出的异常 的相关文章

  • 获取枚举实例的名称[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 假设我有这个枚举 public enum MyEnum ValueOne 1 ValueTwo 2 ValueThree 3 然后
  • 通过指向基址的指针删除对象而不使用虚拟析构函数

    我有代码 class A1 public A1 cout lt lt A1 virtual A1 cout lt lt A1 class A2 public A2 cout lt lt A2 A2 cout lt lt A2 class B
  • 任何reinterpret_cast改变指针值的真实例子?

    根据 C 标准 reinterpret cast一个指针的T 到其他类型的指针Q 可以改变或不改变指针值 https stackoverflow com questions 1863069 casting via void instead
  • 如何使用c#/VB.NET在word中插入书签

    我正在尝试使用 C 在 Word 文档中添加书签 但它不起作用 而且我在 msdn 文档和互联网上都找不到任何帮助 这就是我正在尝试做的事情 我正在阅读 Word 文档 然后在该文档中搜索关键字 然后将该文本转换为超链接 效果很好 现在 我
  • 当假设 [[assume]] 包含 UB 时会发生什么?

    在 C 23 中 assume expression 属性使得如果表达 is false 行为未定义 例如 int div int x int y assume y 1 return x y 这会编译成相同的代码 就像y一直是1 div i
  • MPI_Gather 分段错误

    我有这个并行高斯消除代码 调用以下任一方法时会发生分段错误MPI Gather函数调用 我知道如果没有为任一缓冲区正确分配内存 可能会出现此类错误 但我看不出内存管理代码有什么问题 有人可以帮忙吗 Thanks Notes 该程序从一个 t
  • 多少次函数调用会导致堆栈溢出

    你好 Android Java 开发者 当一个函数调用一个函数并且该函数调用另一个函数等等时 有多少次调用 堆栈长度 会让我陷入堆栈溢出 有一般经验法则吗 我问的原因是因为我现在对于我的 5 人纸牌游戏来说哪个更有效 设计明智 解决方案一
  • 如何在提升日期时间中忽略周末和节假日?

    第一个问题 我有一个提升日期对象 如下所示 boost gregorian date 今天 2012 02 13 我从今天减去日期部分 如下所示 今天 月 240 或今天 天 X 等 我想在进行上述减法时是否有办法排除周末和特殊假期 我的意
  • 使用迭代器遍历 boost::ublas 矩阵

    我只是想从头到尾遍历一个矩阵 触及每个元素 然而 我发现升压矩阵没有一个迭代器 而是有两个迭代器 而且我无法弄清楚如何使它们工作以便您可以遍历整个矩阵 typedef boost numeric ublas matrix
  • Eiffel 中的错误处理示例

    我在 Eiffel 中找不到任何实际的错误处理示例 我只找到一些例子 要么是微不足道的 要么完全忽略错误 要么将错误处理留给读者 我有兴趣了解在没有异常的情况下错误如何通过调用堆栈 例如 我想知道发送网络请求的应用程序如何通知用户在调用链中
  • 使用 C# 从文本中删除数字

    我有一个要处理的文本文件 其中有一些数字 我只想要其中的文字 而不是其他任何东西 我成功删除了标点符号 但是如何删除数字呢 我想要使 用 C 代码 另外 我想删除长度大于 10 的单词 如何使用 Reg 表达式来做到这一点 您可以使用正则表
  • 如何在C#中使用默认浏览器打开带有锚点(#)的html文件

    我正在尝试在 C 中打开上下文帮助文件 当我没有指定锚点时 它工作得很好 Process Start C Help Help htm 但是当我指定锚点时 它不会打开 Process Start C Help Help htm Toc3420
  • 确定所选电子邮件是来自收件箱还是已发送邮件

    我正在编程Outlook 插件并需要确定所选电子邮件是否来自Inbox or Sent Items这样当我将电子邮件保存到数据库中时 我可以使用文件夹 收件箱 或 已发送 来标记电子邮件 我知道我可以将文件夹名称与 收件箱 或 已发送邮件
  • try-catch 块是否会降低性能[重复]

    这个问题在这里已经有答案了 This link http www cplusplus com doc tutorial exceptions states 为了捕获异常 我们必须将一部分代码放在异常下 检查 这是通过将这部分代码包含在 tr
  • 以编程方式打开网页并以字符串形式检索其 html 包含内容

    我有一个 Facebook 帐户 我想提取我朋友的照片及其个人详细信息 例如 出生日期 就读学校 等 我能够提取我每个朋友帐户的 Facebook 首页的地址 但我不知道如何以编程方式打开我每个朋友首页的网页并将 html 包含保存为字符串
  • 使用循环在 C 中管道传输两个或多个 shell 命令

    我正在尝试执行ls wc l通过 C 语言程序 而不是使用命令行 这是我当前的工作代码 int main int pfds 2 pipe pfds pid t pid fork if pid 0 The child process clos
  • MSVC如何在编译期间输出一些内容到“输出”窗口

    有时我看到某些项目在编译期间向输出写入一些内容 在MSVC 中如何实现 thanks use pragma message e g define MESSAGE t message FILE STRINGXXX LINE t define
  • Linq 表达式树 Any() 问题

    您好 我在使用 Any 扩展方法的表达式树时遇到问题 这是我的代码 IQueryable
  • 如何在 C# 中使用 Selenium WebDriver 获取当前窗口的 URL?

    在我的应用程序中 登录时 它会导航到另一个页面 现在我需要在 selenium C 中使用 WebDriver 获取新的 URL 我找不到任何函数来执行此操作 我努力了driver Url driver getLocation and dr
  • 复杂对象上的 GroupBy(例如 List

    Using GroupBy and Count gt 1我试图在列表中查找我的类的重复实例 该类看起来像这样 public class SampleObject public string Id public IEnumerable

随机推荐

  • 我什么时候必须创建异步存根

    ManagedChannel managedChannel ManagedChannelBuilder forAddress localhost 8888 usePlaintext build Grpc Stub stub CLIGrpc
  • Android 中最近的设备更新存在 Toast 通知问题

    这篇文章与现有的已提交错误相关 https groups google com forum topic android developers K7pjy3Gm5Lk discussion https groups google com fo
  • WPF加载序列化图像

    在应用程序中 我需要通过二进制编写器序列化图像 并将其获取到其他应用程序中以显示它 这是我的 序列化 代码的一部分 FileStream fs new FileStream file FileMode Create FileAccess W
  • 使用 ImageIO.read 时出现问题

    好的 我有一张正在尝试阅读的图像 问题是 Image read file 返回 NULL File file new File C images image1 jpg if file exists System out println Im
  • 如何设置“UILabel”的字符间距(紧排)和删除线样式?

    我需要为由 a 呈现的文本设置两个属性UILabel 字母之间的间距 kern 及其删除线样式 基于NSAttributedStringKey文档 我已经创建了以下扩展UILabel extension UILabel func setSt
  • WCF 使用匿名方法关闭连接

    在我们的项目中 我们使用以下代码进行 WCF 调用 In generated Proxy we have public static ICustomer Customer get ChannelFactory
  • ZF2 Form Hydration 具有多个对象和字段集

    我正在努力尝试弄清楚如何使用单个表单编辑多个模型 我有一个名为 Teams 的数据库表和一个与该表关联的条令实体 我创建一个表格如下 我的团队字段集 class TeamFieldset extends AbstractFieldset i
  • 我可以在 C++ 工厂中声明的同一行使用变量吗?

    我有一个多态的类层次结构 虽然我也支持标准工厂方法 即仅使用基类指针 但我还想要一个为我提供派生类的工厂机制 这并不容易 因为这些函数仅在返回类型上有所不同 这就是为什么我想到重载函数并让编译器选择正确的函数的原因 一个简单的应用是 我可以
  • F# 的情况如何? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 简单的 C Java 代码非常难以并行化 多线程等 因此 简单的 C Java 代码将使用越来越少的机器上的总处理能力 因为现在一切都将是多核的
  • 两个类之间的 ActionListener

    导入 javax swing 类标签扩展 JFrame JPanel pnl new JPanel ImageIcon duke new ImageIcon duke png JLabel lbl1 new JLabel duke JLab
  • 升级到 Google Play Services 9.0.0 后,应用程序在 DynamiteModulesC 中挂起

    通过这些更改和重新生成 将开发中的应用程序升级到 9 0 0google services json classpath com google gms google services 3 0 0 compile com google and
  • 如何在 VS Code 中正确集成 Cmder 2021 年 4 月?

    我想将 Cmder 集成到我的 Vscode 设置中 但在 2021 年 4 月的 vscode 更新中 命令 terminal integrated shell windows 和 terminal integrated shellArg
  • 强制 WPF TextBox 在 .NET 4.0 中不再工作

    在我的 WPF 应用程序中 我有一个文本框 用户可以在其中输入百分比 作为 int 介于 1 和 100 之间 Text 属性与 ViewModel 中的属性进行数据绑定 我在其中强制将值置于 setter 中的给定范围内 但是 在 NET
  • 在 Neo4J 中,当索引已存在时启动 CREATE INDEX ON

    如果您在已有此索引的 Neo4J 数据库上重播 CREATE INDEX ON 命令 会发生什么情况 Neo4J 是否会简单地忽略该命令 第一次执行它时 Neo4j 将 创建索引 创建一个后台作业来填充它 作为查询统计信息 告诉您索引已创建
  • 我可以取回 MySQL 表中列名的默认值吗? [复制]

    这个问题在这里已经有答案了 我可以获取表的列名称 但有没有办法检索每列的默认数据值 这是我用来获取表列名称的方法 q dbh gt query DESCRIBE tablename table fields q gt fetchAll PD
  • 错误:在 NDK 工具链文件夹中找不到 ABI 的工具链,前缀为:arm-linux-androideabi

    我对 Android Studio 真的很陌生 我正在快速移动并从我的代码中删除了一些内容 现在我不断收到错误消息并且我的 gradle 同步失败 我在日志中看到以下内容 2016 06 01 05 39 55 358 32778590 W
  • keydown 事件覆盖返回键在 Firefox 中不起作用

    我有以下简单的 javascript 代码 它处理返回键 我不想在文本框中按下返回键时提交表单 所有这些工作正常 但在 Firefox 中 如果我显示一条警报消息 那么它会停止工作并且开始提交表单 而没有警报消息的确切代码工作正常并停止提交
  • 如何计算可迭代对象中的非空元素数量?

    我正在为以下代码片段寻找更好 更 Pythonic 的解决方案 count sum 1 for e in iterable if e len list filter None iterable Using None作为谓词filter只是说
  • 使用 GDAL 和 Python 的最小距离算法

    我正在尝试实施最短距离算法使用 GDAL 和 Python 进行图像分类 计算样本区域的平均像素值并将其存储到数组列表 sample array 中后 我将图像读入名为 values 的数组中 使用以下代码循环遍历该数组 values va
  • WPF DataBinding 监视抛出的异常

    在我的模型中 我有很多不同对象的属性 我在设置对象值时检查该值 如果该值不被接受 我将抛出一个异常 这与 Windows 窗体 propertygrid 完美配合 但现在我正在尝试使用 WPF 设计新界面 在WPF中 当我将属性绑定到文本框