首页 > 解决方案 > 如何区分来自类内部或外部的依赖属性更改

问题描述

我正在创建一个 WPF 自定义控件。该控件是一个时间选择器。它存在一个TextBox包含表示用户输入时间的字符串(如 16:35)。当该 TextBox 被聚焦时,aPopup打开,其中包含两个单独的 TextBox,分别代表小时和分钟,以便于输入。

在此处输入图像描述

弹出文本框和主字段文本框应该同步。我的意思是,当用户通过单击箭头键或在小小时字段中键入来更改小时时,主文本框(包含文本 16:35)应该更新,反之亦然。弹出窗口中的字段仅限于接受 [0-9] 字符。当主 TextBox 时间字符串发生变化时,会解析字符串并更新 Popup 中的两个字段。如果用户在主文本框中键入了无效的时间字符串,并且控件无法从中提取小时和分钟来更新弹出文本框,那么我什么也不做。

弹出窗口中的箭头按钮绑定到命令。

我只使用自定义控件的类。我不附加任何 DataContext,我只想使用依赖属性。

我的控件有多个依赖属性,包含我的控件的用户视图应该使用以下依赖属性:

对于内部工作,我还有一些依赖属性:

我的问题示例:

当用户更改任何字段时,必须同步总控制字段。因此,如果 Popup 的小时字段中的文本发生更改,则主字段的时间字符串也会更改。我通过使用在依赖属性元数据中定义的依赖属性更改回调来做到这一点。但问题是,使用此回调,您不知道更改是来自设置 DP 值的类本身的控制模板(直接来自用户的操作)。这会导致恶性循环,您很快就会失去概览。并不是我的程序崩溃了,而是出现了问题,例如 DP 更新了两次以及那种不需要的行为。

  1. 用户在其中输入时间字符串更改了 TextBoxText (12:45)
  2. DP回调被调用是因为TextBoxText DP改变了它的值,所以控件想要更新Popup中的TextBoxes
  3. 解析 TextBoxText 字符串并将 DP Hour 和 Minute 设置为新值。
  4. 调用 DP Hour 回调,并调用 DP Minute 回调。
  5. 在这个 Hour and Minute DP 回调中,必须更新 TextBoxText -> 导致循环(参见步骤 2)。因为它不区分来自“外部”(使用控件的视图用户)或“内部”(更改自己的 DP 的控件类)的更改。

如何解决这个问题?有这方面经验的人还是我做错了什么?

标签: c#wpfdependency-propertiestimepicker

解决方案


我大部分时间都是这样处理的:

伪代码:

callback(){
   if(flag){
      it's coming from program
   }
   else{
      it's coming from user
   }
}

button_event_handler(){
   flag = true
   do_stuff()
   flag = false
}

但是,如果这不适用于您的代码,还有其他方法可以做到这一点。

例如,在日期时间部分等复杂值的情况下,您可以将实际的 DateTime 存储在一个属性中,该属性通过转换器绑定到每个控件。它必须是单射的,否则整个事情将陷入循环。通过单射,我的意思是 updown 控件的每个状态必须只有一个文本框状态,反之亦然。


推荐阅读