2017-10-05 8 views
0

PropertyChangedCallback을 사용하여 종속성 속성이있는 사용자 지정 컨트롤이 있습니다. 속성 값은 사용자 정의 컨트롤 논리에서 또는 사용자 상호 작용 또는 클라이언트 응용 프로그램에서 설정 한 값에 의해 변경되지 않고 변경 될 수 있습니다.PropertyChangeCallback - 컨트롤 내에서 변경되었는지 여부

속성이 변경된 원인을 알려주는 방법이 있습니까?

나는 "보낸 사람"을 보았지만 각 경우에 보낸 사람은 사용자 지정 컨트롤 자체입니다.

는 설명하기 :
public static readonly DependencyProperty SelectedTimeProperty = 
     DependencyProperty.Register("SelectedTime", typeof(DateTime?), typeof(TimePickerControl), new PropertyMetadata(null, new PropertyChangedCallback(HandleSelectedTimeChanged))); 

    public static readonly DependencyProperty HoursProperty = 
     DependencyProperty.Register("Hours", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnHoursChanged(o, e.OldValue))); 

    public static readonly DependencyProperty MinutesProperty = 
     DependencyProperty.Register("Minutes", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnMinutesChanged(o, e.OldValue))); 

    public static readonly DependencyProperty SecondsProperty = 
     DependencyProperty.Register("Seconds", typeof(object), typeof(TimePickerControl), new PropertyMetadata(@"", (o, e) => ((TimePickerControl)o).OnSecondsChanged(o, e.OldValue))); 

그래서 클라이언트 응용 프로그램이 Hours, MinutesSeconds이 제어에 의해 갱신 될 수있는 경우에 SelectedTime를 업데이트 할 수 중 하나. 이 논리는 HandleSelectedTimeChanged에서 처리됩니다.

그러나, 사용자는 또한 SelectedTime 그에 따라 업데이트 할 것입니다있는 Hours 중 하나 MinutesSeconds을 수정할 수 있습니다. 말하자면,의 변화는 Hours이 시간을 변경 물론 어떤의 SelectedTime 콜백이 트리거 될 것이기 때문에 당신이 아마 추측 수 있듯이

은,이 루프의 비트를 생성/(분) /는 초 자신의 콜백을 호출하는 다시 한 번 트리거됩니다.

변경 사항이 컨트롤 외부에서 왔을 경우에만 콜백을 호출하거나 콜백 내에서이를 감지하여 너무 빨리 종료합니다.

내가 지금까지 생각해 낸 유일한 아이디어는 속성 중 하나를 변경하기 전에 즉각적으로 개인 변수를 설정하고 설정되면 콜백 exit 내에서 변경 한 후 즉각적으로 초기화하지만 매우 지저분 해 보입니다. 나에게. 이 작업을 수행하는 더 좋은 방법이 있습니까?

+0

종속성 속성은 컨트롤 안에 있습니다. 컨트롤 내에서 값을 변경하는 경우 일부 플래그를 사용하면됩니다. 변경하기 전에 설정하고 콜백에서 확인하십시오. 또 다른 것은 [강요] (https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-callbacks-and-validation#coerce-value-callbacks-and-property-changed)입니다. -events). – Sinatr

+1

_ "아마 추측 할 수 있듯이, 이것은 약간의 루프를 만듭니다."_ 이런 일이 있어서는 안됩니다. 속성 변경 콜백은 속성 값이 실제로 변경 될 때만 호출됩니다. 따라서'Hours' 속성을 변경하면 콜백 함수는'SelectedTime' 속성을 설정합니다. 그러면 'Hours' 속성 값이 다시 설정됩니다. 그러나 'Hours' 속성 값은 변경되지 않았으므로 속성 변경 콜백이 호출되지 않습니다. 나는 당신의 문제가'Hours','Minutes' 및'Seconds' 의존성 프로퍼티를 ** type ** 객체로 선언하는 것과 관련이 있다고 생각합니다. 그들은 ** int **일까요? –

+0

@StevenRands - 무한 루프가 아니며, 여러분이 말하는 것을 깨닫지 만, 복잡한 스파게티 흐름을 만들어서 읽기/디버그/유지 보수가 어려우며 컨트롤 내에서 다른 문제를 일으킬 수 있습니다. – colmde

답변

0

바깥에서 변경 이벤트를 시작하는 것은 가능하지 않습니다. 매우 일반적인 시나리오로 직면하고 있으며 몇 가지 해결책이 있습니다.

  1. 첫 번째 최상의 솔루션은이 시나리오를 완전히 피하는 것입니다. 귀하의 경우

는 대신 시간의 각 구성 요소에 대한 여러 종속 특성을 갖는 단 각각에 대한 정의 값 변환을 작성하고 필요한 변환기와 단일 SelectedTime 속성 값을 결합하는 것을 의미한다. 나는 개인적으로이 방법을 적극 추천한다.

  1. 두 번째 방법은 필요에 따라 변경하는 것입니다. 귀하의 경우에는

이 시간이 업데이트 여부를해야하는지 UpdateHour 검사를 트리거하기 전에 의미한다. 그렇지 않으면 트리거하지 마십시오. 그것은 깔끔한 방법이고 업데이트 루프를 자르지 만 성능 오버 헤드가 있습니다.

  1. 세 번째 방법은 Dirty 플래그가 있습니다.

이것은 다소 말한 내용입니다.값이 false 인 SelectedDate에 대한 부울 플래그를 유지합니다. 변경되면 true로 설정하고 true이면 다음 루프에서 종료하고 false로 다시 설정합니다.

당신이 말했듯이 그것은 지저분하고 부정합니다. 그러나 일을 끝내게됩니다.

+0

왜 downvote? 댓글을 남길 수있는주의 사항? – Emad

+1

나는 "더러운 깃발"방법으로 갔다 ... – colmde