성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <br /> <div class='mainCenterTitle'>WPF - RadioButton 데이터 바인딩 해제 현상</div><br /> <br /> 개인적으로, WPF에서 실망스러운 컨트롤이 RadioButton입니다. 제 개인적인 WPF에 대한 이해도가 깊지 않아서든, 혹은 "by design"이란 변명이 아무리 그럴싸할지라도! 이 현상은 "일반적인 개발 상식"으로 XAML을 다루다 보면 누구나 만날 수 있는 현상이기 때문입니다.<br /> <br /> 일단, 간단하게 재현을 해볼까요!<br /> <br /> 아래와 같이, 평범한 RadioButton을 나열해 놓는 xaml 파일을 만듭니다.<br /> <br /> <pre class='code'> <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:WpfApplication1" x:Name="My"> <Canvas> <<b>RadioButton</b> IsChecked="{<b>Binding Path=DisplayData.Radio1</b>, ElementName=My}" Name="radioButton1">test1</<b>RadioButton</b>> <<b>RadioButton</b> IsChecked="{<b>Binding Path=DisplayData.Radio2</b>, ElementName=My}" Name="radioButton2" Height="16" Canvas.Top="20">test2</<b>RadioButton</b>> <<b>RadioButton</b> IsChecked="{<b>Binding Path=DisplayData.Radio3</b>, ElementName=My}" Name="radioButton3" Height="16" Canvas.Top="40">test3</<b>RadioButton</b>> </Canvas> </Window> </pre> <br /> xaml.cs 파일에는 아래와 같이 데이터 바인딩을 위한 코드를 구성합니다.<br /> <br /> <pre class='code'> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private DisplayT displayData = new DisplayT(); <b>public DisplayT DisplayData</b> { get { return this.displayData; } } } </pre> <br /> DisplayT는 다음과 같이 간단하게 정의되어 있습니다.<br /> <br /> <pre class='code'> public partial class DisplayT { private bool radio1; private bool radio2; private bool radio3; public bool <b>Radio1</b> { get { return this.radio1; } set { this.radio1 = value; } } public bool <b>Radio2</b> { get { return this.radio2; } set { this.radio2 = value; } } public bool <b>Radio3</b> { get { return this.radio3; } set { this.radio3 = value; } } public DisplayT() { } public override string ToString() { return string.Format("radio1 == {0}, radio2 == {1}, radio3 == {2}", this.radio1, this.radio2, this.radio3); } } </pre> <br /> 빌드하고, 실행을 해보시면 뭐 그다지 표면상으로는 이상한 현상이 없어 보입니다. 하지만, 문제점을 보여주기 위한 테스트 코드를 1초마다 발생하는 타이머 이벤트에 다음과 같이 걸어보면,<br /> <br /> <pre class='code'> public Window1() { InitializeComponent(); DispatcherTimer timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, callback, App.Current.Dispatcher); } public void callback(object sender, EventArgs e) { Debug.WriteLine(displayData); } </pre> <br /> 뜻밖에도, 실행 후에 Radio 버튼 1,2,3을 모두 한번씩이라도 눌러본 경우, 데이터바인딩이 된 DisplayT 타입의 변수에는 Radio1 == True, Radio2 == True, Radio3 == True라는 엉뚱한 결과값이 실려서 출력이 됩니다.<br /> <br /> 사실, RadioButton이 그룹 설정이 되어 있는 경우에만 서로간의 배타적인 선택권이 가능하다는 점을 고려하면 위의 현상이 아주 이해못할 것도 아닙니다. 하지만, 그걸 감안하면 각각의 RadioButton들이 모두 Checked == True 상태로 남은 체로 있어야 하는 것이 정상입니다. 그런데, 결과는 UI 따로, 데이터 바인딩 따로입니다.<br /> <br /> 조금 더 테스트를 위해 callback 메서드에 다음과 같이 데이터 바인딩이 살아 있는지에 대한 테스트 코드를 추가해 보겠습니다.<br /> <br /> <pre class='code'> public void callback(object sender, EventArgs e) { <b>CheckBinding</b>(this.radioButton1); <b>CheckBinding</b>(this.radioButton2); <b>CheckBinding</b>(this.radioButton3); Debug.WriteLine(displayData); } private void CheckBinding(RadioButton button) { Binding test = <b>BindingOperations.GetBinding</b>(button, RadioButton.IsCheckedProperty); if (<b>test == null</b>) { Debug.WriteLine(string.Format("{0} Binding == null", button.Content)); } } </pre> <br /> "F5" 키를 이용해서 디버깅 모드로 응용 프로그램을 실행한 후, 각각의 Radio 버튼들을 누르면 방금 전에 선택된 Radio 버튼들에 대해서 바인딩 인스턴스가 null로 되는 것을 확인할 수 있습니다. 3개 모두 누르면 다음과 같이 3개 모두 바인딩이 끊기게 됩니다.<br /> <br /> <pre class='code'> ==== Output 내용 ==== test1 Binding == null test2 Binding == null test3 Binding == null radio1 == True, radio2 == True, radio3 == True </pre> <br /> 분명히, 이러한 결과는 우리가 원한 것이 아니지요.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 물론, 해결책은 있습니다. ^^<br /> WPF를 초기 시절부터 공부해오신 분들은 RadioButtonList 컨트롤에 대해 알고 계실 텐데요. 이것이 나중에 Obsolete으로 바뀌면서 아예 WPF에서 빠지게 됩니다. 대신에, 그에 대한 대안으로 ListBox의 ContentTemplate을 변경하는 방법으로 - 지극히 WPF스러운 방식이죠. - 제공이 됩니다. 이에 대해서는 다음의 토픽에서도 잘 설명되고 있습니다.<br /> <br /> <pre class='code'> Data-binding to a radio button group ; <a target='_tab' href='https://social.msdn.microsoft.com/Forums/en-US/323d067a-efef-4c9f-8d99-fecf45522395/databinding-to-a-radio-button-group?forum=wpf'>https://social.msdn.microsoft.com/Forums/en-US/323d067a-efef-4c9f-8d99-fecf45522395/databinding-to-a-radio-button-group?forum=wpf</a> RadioButton unchecked bindings issue still not resolved? ; <a target='_tab' href='https://social.msdn.microsoft.com/Forums/en-US/8eb8280a-19c4-4502-8260-f74633a9e2f2/radiobutton-unchecked-bindings-issue-still-not-resolved?forum=wpf'>https://social.msdn.microsoft.com/Forums/en-US/8eb8280a-19c4-4502-8260-f74633a9e2f2/radiobutton-unchecked-bindings-issue-still-not-resolved?forum=wpf</a> </pre> <br /> 첨부된 파일인 "<a target='_tab' href='/bbs/DownloadAttachment.aspx?fid=427&boardid=331301885'>WpfApplication1.zip</a>"은, 위에서 문제점을 짚은 예제 소스 코드이고, "<a target='_tab' href='/bbs/DownloadAttachment.aspx?fid=428&boardid=331301885'>WpfApplication2.zip</a>"은 이를 해결한 간단한 예제 소스 코드입니다.<br /> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1172
(왼쪽의 숫자를 입력해야 합니다.)