简体   繁体   English

ReadOnlyCheckBox ControlTemplate

[英]ReadOnlyCheckBox ControlTemplate

I've been trying to create my generic ReadOnlyCheckBox style/template but I'm having a problem with the binding to the data. 我一直在尝试创建通用的ReadOnlyCheckBox样式/模板,但是绑定到数据时遇到了问题。 In the example here: 在此处的示例中:

A read-only CheckBox in C# WPF C#WPF中的只读CheckBox

you bind directly to the data from the ControlTemplate definition, but of course this is not really what I want, as I want to be able to declare the new checkbox something like this: 您直接绑定到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"/>

Except of course when I do this and then set the event trigger on the bullet to be a TemplateBinding of IsChecked I have exactly what I started with! 当然,除了当我执行此操作然后将项目触发条件设置为IsChecked的TemplateBinding时,我完全是从我开始的! I guess I don't understand why setting the binding directly in the bullet is different from setting IsChecked and then binding to that, isn't the TemplateBinding just a way of referencing what is set in the properties of the control being created? 我想我不明白为什么直接在项目符号中设置绑定与设置IsChecked然后绑定到该绑定不同,TemplateBinding不仅仅是引用正在创建的控件属性中设置的内容的方式吗? How is the Click triggering the UI update even tho the data does not get updated? 即使数据未更新,单击如何触发UI更新? Is there a trigger for Click I can override to stop the update? 单击“我可以覆盖以停止更新”是否存在触发器?

I got all the DictionaryResource stuff working fine so I am happy with that, cheers for the pointer. 我所有的DictionaryResource东西都工作正常,所以我对此感到高兴,为指针欢呼。

The other thing I was curious about was if it is possible to reduce my Control/Style template by using the BasedOn parameter in the style, then I would only override the things I actually need to change rather than declaring a lot of stuff that I think is part of the standard template anyway. 我好奇的另一件事是,如果可以通过使用样式中的BasedOn参数来减少我的Control / Style模板,那么我只会覆盖我实际需要更改的内容,而不是声明很多我认为的内容仍然是标准模板的一部分。 I might have a play with this. 我可能会玩这个。

Cheers 干杯

ed

The problem you're running into is that you're trying to use DataBinding where you shouldn't. 您遇到的问题是您试图在不应该使用的地方使用DataBinding。

I disagree with other answers you've been getting in the link you've posted. 我不同意您在发布的链接中获得的其他答案。 While the ControlTemplate solutions appear neat and tidy, they don't get at the heart of your problem, which is, you're trying to use a single control (a CheckBox) to do two different things: show state (eg checked/unchecked) and perform logic (remote device, etc.). 虽然ControlTemplate解决方案看起来很整洁,但它们并没有成为您问题的核心,也就是说,您正在尝试使用单个控件(一个CheckBox)来做两种不同的事情:显示状态(例如,选中/未选中) )并执行逻辑(远程设备等)。

ControlTemplates are designed to change the way a control appears , but not behaves . ControlTemplates旨在更改控件的显示方式 ,但不能改变其行为 You're trying to change behavior, not appearance. 您正在尝试更改行为,而不是外观。 See "What Is a ControlTemplate?" 请参阅“什么是ControlTemplate?” here for more details 在这里了解更多详情

To do that, you're going to have to store some forego the standard binding and handle some events: 为此,您将不得不放弃一些标准绑定并处理一些事件:

XAML: 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>

Code-Behind: 代码隐藏:

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;
        }

    }
}

The above code example gives you the ability to execute some code async via BackgroundWorker -- I've put in a Thread.Sleep as a placeholder. 上面的代码示例使您能够通过BackgroundWorker执行一些异步代码-我已将Thread.Sleep用作占位符。 I'm also using foo.IsEnabled as a sentinel value in foo_Checked, but you may need some extra state here to handle all of your cases (for instance, going from Checked to Unchecked). 我还在foo_Checked中将foo.IsEnabled用作哨兵值,但是在这里您可能需要一些额外的状态来处理所有情况(例如,从Checked变为Unchecked)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM