我一直在尝试创建我的通用ReadOnlyCheckBox样式/模板,但在绑定到数据时遇到了问题。在下面的示例中:
A read-only CheckBox in C# WPF
您可以直接绑定到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的TemplateBinding时,我就得到了我开始使用的东西!我想我不明白为什么直接在项目符号中设置绑定与设置IsChecked然后绑定不同,难道TemplateBinding不只是引用正在创建的控件的属性中设置的内容的一种方式吗?即使数据没有更新,单击如何触发UI更新?是否有用于Click I override以停止更新的触发器?
我让所有DictionaryResource的东西都工作得很好,所以我很高兴,为指针干杯。
我好奇的另一件事是,如果有可能通过在样式中使用BasedOn参数来减少我的控件/样式模板,那么我将只覆盖我实际需要更改的东西,而不是声明许多我认为是标准模板的一部分的东西。我可能会玩这个游戏。
干杯
边缘
发布于 2009-06-08 23:13:59
您遇到的问题是,您试图在不应该使用DataBinding的地方使用它。
我不同意你在你发布的链接中得到的其他答案。虽然ControlTemplate解决方案看起来很整洁,但它们并没有触及问题的核心,即,您试图使用单个控件( CheckBox)来做两件不同的事情:显示状态(例如,选中/未选中)和执行逻辑(例如,远程设备等)。
ControlTemplates旨在更改控件显示的方式,但不能更改的行为。你想要改变的是行为,而不是外表。有关更多详细信息,请参阅"What Is a ControlTemplate?“here
要做到这一点,您将不得不存储一些放弃标准绑定的内容并处理一些事件:
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;
}
}
}上面的代码示例使您能够通过BackgroundWorker异步执行一些代码--我放入了一个Thread.Sleep作为占位符。我还使用foo.IsEnabled作为foo_Checked中的一个标记值,但这里可能需要一些额外的状态来处理所有情况(例如,从选中状态变为未选中状态)。
https://stackoverflow.com/questions/966984
复制相似问题