0

一般的な ReadOnlyCheckBox スタイル/テンプレートを作成しようとしましたが、データへのバインディングに問題があります。ここの例では:

C# WPF の読み取り専用 CheckBox

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 を設定してからそれにバインドすることと異なる理由が理解できないと思います. データが更新されない場合でも、クリックはどのように UI の更新をトリガーしますか? 更新を停止するための [上書きできるクリック] のトリガーはありますか?

DictionaryResource のすべての機能が正常に動作するようになったので、満足しています。ポインターに乾杯します。

私が興味を持っていたもう 1 つのことは、スタイルで BasedOn パラメーターを使用してコントロール/スタイル テンプレートを減らすことができるかどうかでした。その場合、私が考える多くのものを宣言するのではなく、実際に変更する必要があるものだけをオーバーライドします。とにかく、標準テンプレートの一部です。私はこれで遊ぶかもしれません。

乾杯

エド

4

1 に答える 1

0

あなたが直面している問題は、すべきでない場所で DataBinding を使用しようとしていることです。

あなたが投稿したリンクで得た他の回答には同意しません。ControlTemplate ソリューションはきちんと整理されているように見えますが、問題の核心に到達していません。つまり、単一のコントロール (CheckBox) を使用して 2 つの異なることを実行しようとしています。 )およびロジックを実行します(リモートデバイスなど)。

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

    }
}

上記のコード例では、BackgroundWorker を介していくつかのコードを非同期で実行できます。プレースホルダーとして Thread.Sleep を配置しました。また、foo_Checked のセンチネル値として foo.IsEnabled を使用していますが、すべてのケースを処理するには、ここで追加の状態が必要になる場合があります (たとえば、Checked から Unchecked への移行)。

于 2009-06-08T23:13:58.823 に答える