readOnlyCheckBox ControlTemplate
-
12-09-2019 - |
문제
나는 일반적인 readonlycheckbox 스타일/템플릿을 만들려고 노력했지만 데이터 바인딩에 문제가 있습니다. 여기의 예에서 :
ControlTemplate 정의의 데이터에 직접 바인딩되지만 물론 새 확인란을 다음과 같이 선언 할 수 있기 때문에 이것은 실제로 원하는 것이 아닙니다.
<CheckBox x:Name="uiComboBox" Content="Does not set the backing property, but responds to it."
Style="{StaticResource ReadOnlyCheckBoxStyle}" IsChecked="{Binding MyBoolean}" Click="uiComboBox_Click"/>
물론 내가 이것을 할 때를 제외하고, 그런 다음, 총알의 이벤트 트리거를 ischecked의 템플릿 결합으로 설정했습니다. 나는 내가 시작한 것을 정확히 가지고 있습니다! 총알에서 직접 바인딩을 설정하는 이유를 이해하지 못한다고 생각하지 않는 것 같아요. 왜 총알에서 직접 바인딩을 설정 한 다음 바인딩하는 것과 다르고, 템플릿 결합은 생성되는 제어의 속성에 설정된 내용을 참조하는 방법이 아닙니다. 클릭이 UI 업데이트를 트리거하는 방법은 어떻게 데이터가 업데이트되지 않습니까? 클릭에 대한 트리거가 있습니까? 업데이트를 중지하기 위해 재정의 할 수 있습니까?
나는 모든 DictionaryResource 물건을 잘 작동 시켰으므로 나는 그것에 만족합니다. 포인터를 응원합니다.
내가 궁금한 또 다른 것은 스타일의 기반 매개 변수를 사용하여 제어/스타일 템플릿을 줄일 수 있다면, 내가 생각하는 많은 것들을 선언하는 대신 실제로 변경해야 할 사항을 무시할뿐입니다. 어쨌든 표준 템플릿의 일부입니다. 나는 이것을 가지고 놀았을 것입니다.
건배
에드
해결책
당신이 달리는 문제는 당신이하지 말아야 할 곳에 데이터베인딩을 사용하려고한다는 것입니다.
나는 당신이 게시 한 링크에서 얻은 다른 답변에 동의하지 않습니다. ControlTemplate 솔루션이 깔끔하고 깔끔하게 보이지만 문제의 핵심을 얻지 못합니다. 즉, 단일 컨트롤 (확인란)을 사용하여 두 가지 다른 작업을 수행하려고합니다. ) 및 로직 (원격 장치 등)을 수행하십시오.
ControlTemplates는 제어 방식을 변경하도록 설계되었습니다 나타납니다, 하지만 행동. 당신은 외관이 아니라 행동을 바꾸려고 노력하고 있습니다. "ControlTemplate 란 무엇입니까?" 여기 자세한 사항은
그렇게하려면 표준 바인딩을 전혀 보관하고 일부 이벤트를 처리해야합니다.
XAML :
<Window x:Class="WPFCheckBoxClickTester.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<CheckBox x:Name="foo" Checked="foo_Checked"></CheckBox>
</Grid>
</Window>
코드-홀드 :
using System.ComponentModel;
using System.Threading;
using System.Windows;
namespace WPFCheckBoxClickTester
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private BackgroundWorker _worker = new BackgroundWorker();
public Window1()
{
InitializeComponent();
foo.IsThreeState = false;
this._worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
this._worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
}
private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
foo.IsChecked = true;
foo.IsEnabled = true;
return;
}
private void _worker_DoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(500);
return;
}
private void foo_Checked(object sender, RoutedEventArgs e)
{
if( foo.IsChecked == true && this.foo.IsEnabled )
{
this.foo.IsChecked = false;
this.foo.IsEnabled = false;
this._worker.RunWorkerAsync();
}
return;
}
}
}
위의 코드 예제는 배경 작업자를 통해 일부 코드 Async를 실행할 수있는 기능을 제공합니다. 저는 자리 표시 자로 스레드를 넣었습니다. 또한 foo.isenabled를 foo_checked의 Sentinel 값으로 사용하고 있지만 모든 케이스를 처리하려면 여기에 추가 상태가 필요할 수 있습니다 (예 : 점검에서 확인되지 않은 상태로 이동).