ReadOnlyCheckBox ControlTemplate - PullRequest
       26

ReadOnlyCheckBox ControlTemplate

0 голосов
/ 09 июня 2009

Я пытался создать свой общий стиль / шаблон ReadOnlyCheckBox, но у меня возникла проблема с привязкой к данным. В примере здесь:

CheckBox только для чтения в 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"/>

За исключением, конечно, когда я делаю это и затем устанавливаю триггер события на маркере как TemplateBinding of IsChecked, у меня есть именно то, с чего я начал! Думаю, я не понимаю, почему установка привязки непосредственно в маркере отличается от установки IsChecked, а затем привязки к ней, не является ли TemplateBinding просто способом ссылки на то, что установлено в свойствах создаваемого элемента управления? Как Click запускает обновление пользовательского интерфейса, даже если данные не обновляются? Есть ли триггер для Click I, который можно переопределить, чтобы остановить обновление?

У меня все отлично работает с DictionaryResource, так что я доволен этим, ура за указатель.

Еще одна вещь, которая меня интересовала, заключалась в том, что если можно уменьшить шаблон элемента управления / стиля с помощью параметра BasedOn в стиле, тогда я переопределю только то, что мне нужно изменить, вместо того, чтобы объявлять много вещей. в любом случае это часть стандартного шаблона. Я мог бы поиграть с этим.

Приветствия

1018 * изд *

1 Ответ

0 голосов
/ 09 июня 2009

Проблема, с которой вы сталкиваетесь, заключается в том, что вы пытаетесь использовать привязку данных там, где не должны.

Я не согласен с другими ответами, которые вы получали по указанной вами ссылке. Хотя решения ControlTemplate выглядят опрятно и аккуратно, они не составляют суть вашей проблемы, то есть вы пытаетесь использовать один элемент управления (CheckBox) для выполнения двух разных задач: показывать состояние (например, отмечен / не отмечен ) и выполнять логику (удаленное устройство и пр.).

ControlTemplates предназначены для изменения способа, которым элемент управления выглядит , но не ведет себя . Вы пытаетесь изменить поведение, а не внешний вид. Смотрите "Что такое шаблон управления?" здесь для более подробной информации

Чтобы сделать это, вам нужно будет сохранить некоторые устаревшие стандартные связывания и обрабатывать некоторые события:

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

    }
}

Приведенный выше пример кода дает вам возможность выполнить некоторый асинхронный код через BackgroundWorker - я поместил Thread.Sleep в качестве заполнителя. Я также использую foo.IsEnabled в качестве значения часового в foo_Checked, но вам может понадобиться дополнительное состояние для обработки всех ваших дел (например, переход от Checked к Unchecked).

...