2009-06-08 38 views
0

我一直在試圖創建我的通用ReadOnlyCheckBox風格/模板,但我遇到了與數據綁定的問題。在這裏的例子:ReadOnlyCheckBox ControlTemplate

A read-only CheckBox in C# WPF

你直接綁定到從控件模板定義中的數據,但當然這不是我真正想要的東西,我希望能夠宣佈新的複選框是這樣的:

 <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不僅僅是引用正在創建的控件的屬性中設置的方法嗎?即使數據沒有得到更新,Click如何觸發UI更新?是否有觸發點擊我可以重寫停止更新?

我得到的所有DictionaryResource的東西工作正常,所以我很高興與指針的歡呼聲。

我很好奇的另一件事是,如果可以通過在樣式中使用BasedOn參數來減少我的Control/Style模板,那麼我只會覆蓋我實際需要更改的事情,而不是聲明很多無論如何,我認爲它是標準模板的一部分。我可能會玩這個。

乾杯

回答

0

你正在運行到的問題是,你想,你不應該使用數據綁定。

我不同意你已經發布的鏈接中獲得的其他答案。雖然ControlTemplate解決方案看起來簡潔而整齊,但它們並不處理問題的核心問題,即您試圖使用單個控件(CheckBox)來執行兩個不同的操作:show state(例如,checked/unchecked )並執行邏輯(遠程設備等)。

ControlTemplates旨在改變控件出現的方式,但不是行爲。你試圖改變行爲,而不是外表。請參閱「什麼是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中的一個標記值,但在這裏可能需要一些額外的狀態來處理所有的情況(例如,從Checked到Unchecked)。

+0

嗨Micahtan, 感謝您的回覆,我很抱歉,花了我很長時間纔回到你身邊,但我轉到了需要完成的緊急項目上。 雖然你的答案可以肯定的工作,但它不覺得我優雅,因爲複選框檢查自己,然後當處理選中的事件時,我們將其設置回來,如果你點擊時看到按鈕,你會看到檢查出現然後消失再次。 理想情況下,我希望能夠編輯模板以禁用點擊發生時的檢查,因此只有在設置它時發生,或者綁定變量需要一個新值。 歡呼 版在此線程 – EdWaugh 2009-07-06 18:14:06

+0

你好的人,我通過基於按鈕創建一個自定義控制解決我的問題,在這裏看到: http://stackoverflow.com/questions/1088906/adding-a-custom-dependency- property-to-a-control-template-in-xaml ed – EdWaugh 2009-07-16 07:26:03