중화사전망 - 서예자전 - WPF 의 사용자 정의 컨트롤에 클릭 이벤트를 추가하는 방법
WPF 의 사용자 정의 컨트롤에 클릭 이벤트를 추가하는 방법
1, 컨트롤에 속성 추가 (DependencyProperty).
다음 코드와 같이 :
공공? 정전기? 읽기 전용? DependencyProperty? 시간 속성? =?
DependencyProperty 등록 ("시간",? Typeof (날짜 시간), type of(ClockUserCtrl),
새 것? FrameworkPropertyMetadata (날짜 및 시간). 지금 새거야? Propertychangedcallback (timepropertychangedcallback)); 컨트롤 (또는 모든 WPF 클래스) 에 추가하는 종속 속성은 "공용", "정적" 및 "읽기 전용" 이고 이름 지정 방법은 "속성 이름+속성" 입니다. 이는 속성에 따라 변경할 수 없는 쓰기 방법입니다. 속성에 의존하는 등록의 경우 DependencyProperty 를 호출할 수 있습니다. Register () 메서드는 속성이 선언될 때 등록됩니다. 정적 생성자에 등록할 수도 있습니다. DependencyProperty 등록 정보의 매개 변수입니다. 위의 Register 메서드에는 속성 이름 (선언된 종속 속성 이름 "XXXProperty" 에 비해 접미사 "property" 만 없고 그렇지 않으면 런타임 시 예외가 보고됨), 속성의 데이터 유형, 속성 소유자의 유형 및 메타데이터가 있습니다.
매개 변수에 전달된 메타데이터 정보: 일반 클래스의 경우 PropertyMetadata 를 전달하고 FrameworkElement 의 경우 FrameworkPropertyMetadata 를 전달합니다. 여기서 FrameworkPropertyMetadata 에 속성을 변경할 때 컨트롤이 어떻게 반응하는지 나타내는 태그를 지정할 수 있습니다. 예를 들어, 속성을 변경하면 컨트롤의 그리기에 영향을 주므로 속성의 메타데이터는 다음과 같이 써야 합니다. 새로운
Framework property metadata (defaulevalue,
Frameworkpropertymetadataoptions. Affects render); 이렇게 하면 속성이 변경될 때 컨트롤 다시 그리기를 고려합니다. 또한 메타데이터는 기본값, 데이터 검증, 데이터 변경 시 콜백 함수, 속성' 상속' 참여 여부 등 많은 콘텐츠를 보호합니다.
그런 다음 종속 속성을 공통 속성으로 포장합니다.
[설명 ("현재 날짜 및 시간 가져오기 또는 설정")]
[범주 ("일반"? 속성 ")"
공공? 날짜 시간? 시간
{
얻다
{
반환? (날짜 시간) 이것. Getvalue (시간 등록 정보);
}
설정
{
이것. SetValue(time property, 값);
}
}GetValue 및 SetValue 메서드는 DependencyObject 클래스에서 파생되며 해당 클래스의 속성 값을 가져오거나 설정하는 데 사용됩니다.
주: 종속 속성을 일반 속성으로 래핑할 때 get 및 set 블록에서 GetValue 및 SetValue 메서드를 점진적으로 호출하는 것 외에는 아무 작업도 수행하지 마십시오. 다음 코드는 적합하지 않습니다.
-응? [설명 ("현재 날짜 및 시간 가져오기 또는 설정")]
[범주 ("일반"? 속성 ")"
공공? 날짜 시간? 시간
{
얻다
{
반환? (날짜 시간) 이것. Getvalue (시간 등록 정보);
}
설정
{
이것. SetValue(time property, 값);
이것. OnTimeUpdated (값) : //오류
}
} 과거에는 많은 사람들이 일반적으로 사용하는 작성 방법이었지만 WPF 에서는 DependencyObject 에서 상속된 클래스에 속성 값을 가져오거나 설정하는 GetValue 및 SetValue 메서드가 있다는 것을 알고 있으므로 이 메서드를 직접 사용하여 속성 값을 가져오거나 설정하는 것이 아니라 순자산? 사실 이 두 가지 방법은 모두 여기에서 가능하지만, 단지 그것이 더 잘 맞는 습관일 뿐이다. 그물 개발자는 그들을 일반으로 포장합니다. NET 속성-JAVA 개발자가 GetValue 및 SetValue 를 사용하는 습관과 비슷하지만 XAML 은 JAVA 개발자와 동일하게 실행되므로 호출되지 않습니다. NET 속성 대신 GetValue 또는 SetValue 메서드를 직접 사용하므로 get 블록과 set 블록에 작성한 다른 코드는 XAML 에서 전혀 실행되지 않습니다. 따라서 위의 시간 속성의 경우 C# (또는 기타) 에서 이 속성을 호출할 때 문제가 발생하지 않지만 XAML 에서 사용할 때 (예: XAML 에서 해당 속성에 데이터 바인딩 등) 문제가 발생합니다. ), 이거. 해당 set 블록의 OnTimeUpdated (값); 이 문은 실행되지 않습니다.
그럼, 시간 속성이 변경 되 면, 당신은 정말 이것을 호출 해야 합니다. OnTimeUpdated (값) : 문 (시간이 업데이트되는 이벤트를 발생시키기 때문) 또는 전달된 종속 속성 메타데이터에 대해 크게 놀란다.
새로운 FrameworkPropertyMetadata (날짜-시간). 이제 새 propertychangecallback (timepropertychangecallback)) 을 만들고 속성 변경 시 실행되는 콜백 함수를 지정합니다.
개인? 정전기? 허공? Timepropertychangedcallback (dependency object? 보낸 사람? Dependencypropertychangedeventargs? Arg) 를 참조하십시오
{
만약? 보낸 사람? ! =? 널? & amp& amp? 보낸 사람? 그래요? ClockUserCtrl)
{
ClockUserCtrl? 시계? =? 보낸 사람? 무엇으로? ClockUserCtrl
시계. On time updated((DateTime)arg 입니다. 이전 값? (날짜 시간) 매개 변수. New value);
}
}2, 컨트롤에 이벤트 추가 (RoutedEvent).
라우팅 이벤트를 추가하는 방법은 관련 속성을 추가하는 방법과 유사합니다.
공공? 정전기? 읽기 전용? RoutedEvent? TimeUpdatedEvent? =?
이벤트 매니저. Registerroutedevent ("timeupdated",
라우팅 정책. 거품? Typeof (routedpropertychangedeventhandler < 날짜 시간>),? Typeof (clockuserctrl); 지원 메소드 이벤트 매니저에 해당하는 매개변수입니다. Registerroutedevent () 는 이벤트 이름, 이벤트 루프 방법 (위로 루프, 아래로 루프 또는 비루프), 이벤트에 해당하는 EventHandler 유형, 이벤트 소유자 유형입니다.
그런 다음 이벤트를 일반 이벤트로 포장하십시오. 네트워크 이벤트:
-응? [설명 ("날짜 또는 시간 업데이트 후 발생")]
공공? 사건? Routedpropertychangedeventhandler < 날짜 시간>? 시간 업데이트
{
증가
{
이것. AddHandler(TimeUpdatedEvent,? 값);
}
제거
{
이것. Remove handler(TimeUpdatedEvent,? 값);
}
} 종속 속성과 마찬가지로 AddHandler 및 RemoveHandler 이외의 코드를 add 및 remove 블록에 추가하지 않도록 주의하십시오.
여하튼 이벤트 매개 변수의 e.Handled=true 는 이벤트의 루프를 종료하기 위한 것이 아니라 이벤트를 표시하기 위한 것이므로 기본적으로 true 로 표시할 때 이러한 이벤트 핸들러가 호출되지 않습니다. True 로 표시된 이벤트에 대한 처리 메서드를 등록하고 실행하려면 다음과 같이 AddHandler 메서드를 사용하고 마지막 매개 변수인 handlerEventsToo 를 true 로 설정합니다.
This.myInkCanvas.AddHandler (
잉크 캔버스. MouseLeftButtonDownEvent,
새 것? MouseButtonEventHandler (
Myinkcanvas _ mouseleftbuttondown),
참);
개인? 허공? Myinkcanvas _ mouseleftbuttondown (
대상? 보낸 사람? MouseButtonEventArgs? E)
{
//해? 어떤 물건
} 그런 다음 일반적인 OnXXX 메서드를 작성하십시오.
보호받고 있습니까? 가상? 허공? OnTimeUpdated (날짜 시간? 이전 값? 날짜 시간? 새로운 가치)
{
Routedpropertychangedeventargs & lt. 날짜 시간>? Arg? =?
새 것? Routedpropertychangedeventargs & lt. 날짜 시간> (이전 값,? NewValue, timeupdatedevent);
이것. Raiseevent (arg);
}3, 컨트롤에 명령을 추가합니다.
WPF 내장 컨트롤과 같은 명령을 사용자 정의 컨트롤에 추가하는 것이 좋습니다 (실제로 이 문장 시리즈의 다음 문장 부분에서 자세히 설명하는 사용자 정의 컨트롤의 인터페이스와 백그라운드 논리 간의 결합을 줄이는 방법이기도 합니다).
WPF 에는 라우팅 명령과 라우팅 명령의 두 가지 유형의 명령이 내장되어 있습니다. 후자에는 인터페이스의 명령에 해당하는 텍스트를 자동으로 현지화하는 추가 텍스트 속성이 있습니다. 자세한 내용은 WPF 명령 및 명령 바인딩 (I) 및 WPF 명령 및 명령 바인딩 (II) 을 참조하십시오.
여기서 우리는 컨트롤의 소리를 통해 시간을 알려주는 명령을 정의했다. 먼저 명령을 정의합니다.
공공? 정전기? 읽기 전용? RoutedUICommand? SpeakCommand? =? 새 것? Routed ui command ("speak",? "말해봐",? Typeof (clockuserctrl);
이러한 매개변수의 이름은 표시 이름, 명령 이름 및 명령 소유자 유형으로 지정됩니다.
그런 다음 컨트롤의 정적 함수에서 명령의 구체적인 세부 사항을 정의하는 명령 바인딩을 정의합니다. 해당 명령은 무엇입니까? 현재 환경에서 어떤 기능을 수행할 수 있습니까?
-응? 명령 바인딩? 명령 바인딩? =? 새 것? 명령 바인딩 (SpeakCommand,? 새 것? Executedroutedeventhandler (executespeak),
새 것? Canexecuteroutedeventhandler (canexecutespace));
개인? 정전기? 허공? ExecuteSpeak (객체? 보낸 사람? ExecutedRoutedEventArgs? Arg) 를 참조하십시오
{
ClockUserCtrl? 시계? =? 보낸 사람? 무엇으로? ClockUserCtrl
만약? 시계? ! =? 비어 있음)
{
시계. Speakthetime ();
}
}
개인? 정전기? 허공? Canexecutespace (개체? 보낸 사람? CanExecuteRoutedEventArgs? Arg) 를 참조하십시오
{
ClockUserCtrl? 시계? =? 보낸 사람? 무엇으로? ClockUserCtrl
Arg. 실행할 수 있습니까? =? 시계? ! =? Null);
}CanExecuteRoutedEventArgs 의} CanExecute 속성은 현재 명령을 사용할 수 있는지 여부를 나타내는 데 사용됩니다. 즉, 명령과 명령의 객체를 계속 보고 제공된 조건에 따라 현재 명령을 사용할 수 있는지 여부를 결정합니다. 예를 들어 텍스트 상자의 상태가 읽기 전용으로 변경되면 해당 붙여넣기 명령을 사용할 수 없으며 텍스트 상자에 작용하는 붙여넣기 버튼은 자동으로 비활성화됩니다. 그렇지 않으면 활성화됩니다.
새로운 executedroutedeventhandler (executespeak) 위임은 ExceteSpeak 함수를 리콜하여 명령을 실행할 때 수행할 작업을 지정합니다.
개인? 정전기? 허공? ExecuteSpeak (객체? 보낸 사람? ExecutedRoutedEventArgs? Arg) 를 참조하십시오
{
ClockUserCtrl? 시계? =? 보낸 사람? 무엇으로? ClockUserCtrl
만약? 시계? ! =? 비어 있음)
{
시계. Speakthetime ();
}
}
개인? 허공? 말하는 시간 ()
{
날짜 시간? 현지 시간? =? 이것. Time.tolocaltime ();
현악? TextToSpeak? =? "지금,"+? 현지 시간. ToShortDateString ()? +","+? 현지 시간. ToShortTimeString ()? +",요일"? +? (정수) 현지 시간입니다. DayOfWeek
This.speecher.speakasync (texttospeak);
} 명령에 바로 가기 키를 추가할 수도 있습니다. 이는 InputBinding 을 통해 구현되며 명령을 명령의 바로 가기 키와 연결합니다. 예를 들면 다음과 같습니다.
바인딩을 입력하시겠습니까? 바인딩을 입력하시겠습니까? =? 새 것? Input binding(speak command, 신규? 마우스 제스처 (마우스 동작. Leftclick);
CommandManager. Registerclassinputbinding (typeof (clockuserctrl),? Input binding);
이렇게 하면 마우스로 컨트롤을 클릭하면 컨트롤의 Speak 명령이 트리거되어 SpeakTheTime 함수를 호출하여 음성 방송을 할 수 있습니다.
바로 가기 키는 MouseGesture 또는 KeyGesture 로 정의할 수 있습니다.