2010-12-01 81 views
5

賞金獎勵的任何可靠的教程/學習資源,用模板化控件連接事件。如何將事件添加到Silverlight中的模板控件?

我有一個這樣的控件模板:

<Style TargetType="local:DatePicker"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="local:DatePicker"> 
       <Border Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}" x:Name="myDatePickerContentArea"> 
        <StackPanel Orientation="Vertical"> 
         <Button x:Name="myTestButton" Content="Test button" /> 
         <telerik:RadDatePicker Style="{StaticResource VisitsReportTextBoxStyle}" Foreground="#FFFFFF" x:Name="startDate" DateTimeWatermarkContent="Start Date"/> 
         <telerik:RadDatePicker Style="{StaticResource VisitsReportTextBoxStyle}" x:Name="endDate" DateTimeWatermarkContent="End Date"/> 
        </StackPanel> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

的C#這個模板是:

public class DatePicker : Control 
{ 

    public static readonly DependencyProperty StartDateSelectedDateProperty = DependencyProperty.Register("StartDateSelectedDateProperty", typeof(DateTime), typeof(DatePicker), null); 
    public DateTime? StartDateSelectedDate { get; set; } 


    public DatePicker() 
    { 
     this.DefaultStyleKey = typeof(DatePicker);    

    } 



    public override void OnApplyTemplate() 
    { 
     RadDatePicker StartDate = this.GetTemplateChild("startDate") as RadDatePicker; 
     StartDate.SelectionChanged += new Telerik.Windows.Controls.SelectionChangedEventHandler(StartDate_SelectionChanged); 
     StartDate.SelectedDate = new DateTime(2010, 01, 01);    
     base.OnApplyTemplate();   
    } 

    void StartDate_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e) 
    { 
     RadDatePicker temp = (RadDatePicker)sender; 
     StartDateSelectedDate = temp.SelectedDate; 
    } 


} 

我的SelectionChanged事件不火,我不知道爲什麼。 任何想法?

+1

如果有人知道模板控件上的任何教程或文章,並且事件示例真的值得讚賞。 – BentOnCoding 2010-12-02 17:27:24

+1

至少我並不孤單,在我的搜索自定義控件的信息。 – BentOnCoding 2010-12-08 21:09:09

回答

4

下面是使用最佳實踐與分選控制的,我認爲你是試圖建立(見尾註的一些解釋)的例子: -

[TemplatePart(Name = DatePicker.ElementStartDate, Type = typeof(RadDatePicker))] 
[TemplatePart(Name = DatePicker.ElementEndDate, Type = typeof(RadDatePicker))] 
public class DatePicker : Control 
{ 
    public DatePicker() 
    { 
     this.DefaultStyleKey = typeof(DatePicker);    
    } 


    #region Template Part Names 
    private const string ElementStartDate = "startDate"; 
    private const string ElementEndDate = "endDate"; 
    #endregion 

    #region Template Parts 
    private RadDatePicker _StartDate; 

    internal RadDatePicker StartDate 
    { 
     get { return _StartDate; } 
     private set 
     { 
      if (_StartDate != null) 
      { 
       _StartDate.SelectionChanged -= StartDate_SelectionChanged; 
      } 

      _StartDate = value; 

      if (_StartDate != null) 
      { 
       _StartDate.SelectionChanged += StartDate_SelectionChanged; 
      } 
     } 
    } 

    private RadDatePicker _EndDate; 

    internal RadDatePicker EndDate 
    { 
     get { return _EndDate; } 
     private set 
     { 
      if (_EndDate!= null) 
      { 
       _EndDate.SelectionChanged -= EndDate_SelectionChanged; 
      } 

      _EndDate= value; 

      if (_EndDate!= null) 
      { 
       _EndDate.SelectionChanged += EndDate_SelectionChanged; 
      } 
     } 
    } 

    #endregion 

    public static readonly DependencyProperty StartDateSelectedDateProperty = 
     DependencyProperty.Register(
      "StartDateSelectedDateProperty", 
      typeof(DateTime?), 
      typeof(DatePicker), 
      new PropertyMetaData(new DateTime(2010, 01, 01))); 

    public DateTime? StartDateSelectedDate 
    { 
     get { return (DateTime?)GetValue(StartDateSelectedDateProperty); } 
     set { SetValue(StartDateSelectedDateProperty)} 
    } 

    public static readonly DependencyProperty EndDateSelectedDateProperty = 
     DependencyProperty.Register(
      "EndDateSelectedDateProperty", 
      typeof(DateTime?), 
      typeof(DatePicker), 
      new PropertyMetaData(new DateTime(2010, 01, 01))); 

    public DateTime? EndDateSelectedDate 
    { 
     get { return (DateTime?)GetValue(EndDateSelectedDateProperty); } 
     set { SetValue(EndDateSelectedDateProperty)} 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate();   

     StartDate = GetTemplateChild(ElementStartDate) as RadDatePicker; 
     EndDate = GetTemplateChild(ElementEndDate) as RadDatePicker; 
    } 

    void StartDate_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e) 
    { 
     // Do stuff with StartDate here 
    } 

    void EndDate_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e) 
    { 
     // Do stuff with EndDate here 
    }  
} 

模板的XAML應該看起來像: -

<Style TargetType="local:DatePicker">         
    <Setter Property="Template">         
     <Setter.Value>         
      <ControlTemplate TargetType="local:DatePicker">         
       <Border Background="{TemplateBinding Background}"         
         BorderBrush="{TemplateBinding BorderBrush}"         
         BorderThickness="{TemplateBinding BorderThickness}" x:Name="myDatePickerContentArea">         
        <StackPanel Orientation="Vertical">         
         <Button x:Name="myTestButton" Content="Test button" />         
         <telerik:RadDatePicker x:Name="startDate" 
          Style="{StaticResource VisitsReportTextBoxStyle}" 
          Foreground="#FFFFFF" 
          DateTimeWatermarkContent="Start Date" 
          SelectedDate="{TemplateBinding StartDateSelectedDate}" 
         />         
         <telerik:RadDatePicker x:Name="endDate" 
          Style="{StaticResource VisitsReportTextBoxStyle}" 
          DateTimeWatermarkContent="End Date" 
          SelectedDate="{TemplateBinding EndDateSelectedDate}" 
         />         
        </StackPanel>         
       </Border>         
      </ControlTemplate>         
     </Setter.Value>         
    </Setter>         
</Style> 

一些解釋

  • 你原來的代碼有一個關鍵的問題是,它沒有正確實施的依賴特性。請注意,屬性現在使用GetValueSetValue,屬性元數據也用於指定默認值,而不是嘗試在onapplytemplate中設置。
  • 由於正確實現了屬性,所以模板綁定應該可以正常工作,事實上,我們已經完成了,看起來像是您的原始意圖,因此我忽略了事件處理程序中的任何實際代碼。
  • 在代碼中創建常量以保存要與之交互的關鍵模板部件的名稱,這可以使名稱更改的製作成本更低。
  • TemplatePart屬性添加到類中,以指示代碼期望找到的關鍵元素,它們的名稱應該是什麼以及它們預期具有的基本類型。這允許設計人員重新模板現有的控件,只要聲明的模板部分存在一些,即使UI的根本改變,控件也應該正常工作。
  • 如果您需要爲某些元素附加事件處理程序,請創建一個字段以保存對該元素的引用,然後創建一個屬性以包圍它。然後,屬性設置器應該像代碼中所看到的那樣分離並附加事件處理程序。
  • 確保bae.OnApplyTemplate在OnApplyTemplate的覆蓋中被調用,然後您可以看到它非常直接地分配上述創建的屬性。
  • 我沒有RadDatePicker,所以我無法測試,我唯一值得關注的地方是DateTime?是SelectedDate屬性的正確類型。當然,如果它是對微軟產品的改進,似乎在這種典型的數據錄入要求上下了功夫。
相關問題