Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何区分类内部或外部的依赖属性更改_C#_Wpf_Dependency Properties_Timepicker - Fatal编程技术网

C# 如何区分类内部或外部的依赖属性更改

C# 如何区分类内部或外部的依赖属性更改,c#,wpf,dependency-properties,timepicker,C#,Wpf,Dependency Properties,Timepicker,我正在创建一个WPF自定义控件。 控件是一个时间选择器。它存在一个文本框,其中包含一个表示用户输入时间的字符串(如16:35)。当该文本框聚焦时,将打开一个弹出窗口,其中包含两个单独的文本框,分别表示小时和分钟,便于输入 弹出文本框和主字段文本框应同步。我的意思是,当用户通过单击箭头键或在小小时字段中键入来更改小时时,主文本框(包含文本16:35)应该更新,反之亦然。弹出窗口中的字段仅限于接受[0-9]个字符。当主文本框时间字符串更改时,将解析字符串并更新弹出窗口中的两个字段。 如果用户在主文

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

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

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

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

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

  • 类型的时间
    TimeSpan
对于内部工作,我还有几个依赖属性:

  • Hour
    类型字符串(与弹出窗口中的Hour文本框绑定)
  • Minute
    类型字符串(与弹出窗口中的Minute文本框绑定)
  • 字符串类型的
    TextBoxText
    (与主文本框绑定)
我的问题示例:

当用户更改任何字段时,必须同步总控制字段。 因此,如果弹出窗口的小时字段中的文本发生变化,则主字段的时间字符串也会发生变化。 我通过使用dependency property元数据中定义的dependency property changed回调来实现这一点。 但问题是,使用此回调时,您不知道更改是否来自控件模板(直接来自用户的操作)或设置DP值的类本身。 这会导致恶性循环,你很快就会失去全局观。这并不是因为我的程序崩溃了,而是出现了一些问题,比如DP被更新了两次,以及那种不必要的行为

  • TextBoxText通过用户在其中键入时间字符串更改(12:45)
  • 调用DP回调是因为TextBoxText-DP更改其值,所以控件希望更新弹出窗口中的文本框
  • TextBoxText字符串被解析,DP Hour和Minute被设置为新值
  • 调用DP Hour回调,调用DP Minute回调
  • 在此小时和分钟DP回调中,TextBoxText必须更新->导致循环(请参阅步骤2)。因为它不区分“外部”(使用控件的视图用户)和“内部”(更改自己DP的控件类)的更改
  • 如何解决这个问题?
    任何有这方面经验的人,或者我做错了什么吗?

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

    伪代码:

    callback(){
       if(flag){
          it's coming from program
       }
       else{
          it's coming from user
       }
    }
    
    button_event_handler(){
       flag = true
       do_stuff()
       flag = false
    }
    
    但是,如果这不适用于您的代码,还有其他方法可以做到这一点


    例如,对于复杂值(如日期时间的一部分),可以将实际日期时间存储在属性中,该属性通过转换器绑定到每个控件。它必须是内射的,否则整个过程将以循环结束。内射是指上下控件的每个状态必须只有一个文本框状态,反之亦然。

    我使用MVVM解决了这个问题。WPF有许多内置的功能,使它变得简单。MVVM方法适合您吗?我可以用这种方式编写一个同步3个文本框的简单示例。MVVM意味着我必须为自定义控件创建一个ViewModel。这意味着我还需要将控件的DataContext显式设置为该ViewModel.sure。我确实考虑过MVVM方法和ValueConverters,但这令人恼火,因为当用户在主字段中键入无效的时间字符串时,我现在什么都不做。当我使用ValueConverter(例如在主字段上)时,当值无法转换时,ValueConverter必须返回类似于
    null
    的值,这意味着DP(绑定到字段)的时间变为
    null
    ,这与什么都不做不同。这一点很好。我现在就来试试。我是按照你的伪代码演示的方式来做的。我为每个回调创建了一个“proxy”方法,它查看标志以确定更改是来自类外部还是来自类内部。效果很好。