2010-07-04 38 views
1

過去,我在win窗體中開發了一個自定義組合框,它實現了自動完成行爲,其中文本的匹配部分以藍​​色突出顯示,而字符串的其餘部分具有正常的背景色。在贏的形式中,這可以使用OwerDraw模式簡單地完成。我需要爲WPF控件做類似的事情。我知道在WPF模板可以用來定製如何顯示控件,但作爲模板本質上是聲明性的我不知道這是如何工作的 - 我需要根據控件的內部狀態來改變文本的繪製方式。我意識到我會做一些閱讀來弄清楚這一點,但作爲WPF是一個大的話題,我會欣賞在正確的大方向的一些指針,所以我知道從哪裏開始尋找。模擬WPF中的OwnerDraw控件

回答

0

在WPF中,控件的外觀由模板,樣式和樣式選擇器組合執行。如果你想根據某些數據的狀態來改變控件的外觀(它可以是控件的內部或外部,它並不重要),那麼你可以將樣式值綁定到這些數據上,當它發生變化時,控件的外觀發生變化(假設有一個通知機制來傳達變化)。您也可以通過稱爲值轉換器(IValueConverter)的類型轉換數據值。這裏

// In a C# class 
public class MyState : INotifyPropertyChanged 
{ 
    public bool IsEmphasized 
    { 
     get { return _isEmphasized; } 
     set 
     { 
      if (_isEmphasized == value) 
      { 
       return; 
      } 

      _isEmphasized = value; 
      OnPropertyChanged("IsEmphasized"); // This is how to notify that the data is updated 
    } 
} 


// A converter 
public class BooleanToBoldConverter : IValueConverter 
{ 
    public Object ConvertTo(Object value) 
    { 
     if (value is bool) 
     { 
      if ((bool)value) 
      { 
       return FontWeights.Bold; 
      } 
      else 
      { 
       return FontWeights.Normal; 
      } 
     } 
    } 
} 

<TextBlock DataContext="{Binding Source={StaticResource myStateInstance}}" 
      FontWeight="{Binding IsEmphasized, Converter={StaticResource BooleanToBoldConverter}}" Text="Text" /> 

雖然這是一個簡單的例子,以及一些細節都省略掉,其主要思想:

舉個簡單的例子,我們可以改變基於基礎數據值的文本塊的文本樣式要理解的是,我們可以以聲明的方式從綁定到屬性和樣式的數據值驅動UI。我們不需要做實際的繪圖。

+0

在此示例中,您將現有控件屬性綁定到某些數據。在自動完成組合框的示例中,我需要更改組合框的文本框(但不是下拉列表中的項目)的繪圖行爲。沒有一個擁有合適屬性的小部件,所以我需要製作一個小部件?也許像TextBlock與整數屬性稱爲HighlightUpToThisIndex? (下文繼續)。 – Shane 2010-07-04 15:39:16

+0

此外,我需要創建一個新的可重用自包含組合框 - 在贏的窗體中,您可以爲現有的自定義創建一個繼承控件。這在WPF中如何工作?也許我想要做的只是你所描述的更復雜的版本,但我還沒有被說服。我想我對WPF還不夠了解。我目前正在閱讀WPF控制開發解鎖 - 也許這會有所幫助。 – Shane 2010-07-04 15:39:43

+0

我看了一下使用反射器的ComboBox代碼。用戶界面的代碼很少,大多數代碼都是關於行爲的,因此codekaizen提到,這是行爲和外觀之間的強烈分離。儘管如此,我認爲定製退出控件的行爲可能會非常具有挑戰性,因爲控件可能並不總是以您所需的詳細程度提供公共鉤子。 – Shane 2010-07-25 12:41:22

0

與WPF一起記住的重要事情是,當你被告知繪製時你不會發出繪圖命令,而是通知渲染系統它應該呈現什麼類型的形狀。如果您想探索低級繪圖,請查看DrawingVisual類,該類允許您在類似於在WinForms畫布上繪製的級別對渲染命令進行排隊。正如codekaizen提到的,這在WPF中通常不是必需的,但是如果您想要在控件中封裝某些特別棘手的事情,或者需要實例化大量這些控件並且需要更好的性能,那麼很好理解。