2017-04-18 135 views
0

我正在創建自定義傳輸控件。GetTemplateChild(「CompactOverlayButton」)按鈕返回Null

我想爲我創建的自定義按鈕設置可見性控件。所以我爲它創建了一個Property。在該屬性中,我使用GetTemplateChild("CompactOverlayButton") as Button來獲取特定的按鈕,但它返回null。

這裏是我的代碼

public bool IsCompactOverlayButtonVisible 
{ 
     get 
     { 
      var compactOverlayButton = GetTemplateChild("CompactOverlayButton") as Button; 
      if (compactOverlayButton.Visibility == Visibility.Visible) 
       return true; 
      else 
       return false; 
     } 
     set 
     { 
      var compactOverlayButton = GetTemplateChild("CompactOverlayButton") as Button; 
      if (value) 
       compactOverlayButton.Visibility = Visibility.Visible; 
      else 
       compactOverlayButton.Visibility = Visibility.Collapsed; 
     } 
} 

但相同的代碼行OnApplyTemplate()函數返回正確的值。

這裏是我的OnApplyTemplate()

protected override void OnApplyTemplate() 
{ 
     var compactOverlayButton = GetTemplateChild("CompactOverlayButton") as Button; 
     compactOverlayButton.Click += CompactOverlayButton_ClickAsync; 
     base.OnApplyTemplate(); 
} 

回答

0

IsCompactOverlayButtonVisible可能被OnApplyTemplate()之前的第一次評估的代碼,這意味着第一次被評估,模板尚未應用和按鈕不存在。在OnApplyTemplate()中,獲取按鈕並將其分配給專用字段。

private Button _compactOverlayButton; 
protected override void OnApplyTemplate() 
{ 
    base.OnApplyTemplate(); 

    _compactOverlayButton = GetTemplateChild("CompactOverlayButton") as Button; 
    _compactOverlayButton.Click += CompactOverlayButton_ClickAsync; 
} 

而在您嘗試觸摸該按鈕的屬性之前,請確保它不爲空。

public bool IsCompactOverlayButtonVisible 
{ 

    get 
    { 
     return _compactOverlayButton != null 
      && _compactOverlayButton.Visibility == Visibility.Visible; 
    } 
    set 
    { 
     if (_compactOverlayButton != null) 
     { 
      compactOverlayButton.Visibility = value 
               ? Visibility.Visible 
               : Visibility.Collapsed; 
     } 
    } 
} 

如果加上之前的模板,例如,如果它是可以在XAML(它看起來會是)來設定控制的公共屬性的東西會設置這個值,你不能這樣做就這樣。你需要使它成爲一個常規的依賴項屬性,給它一個PropertyChanged處理程序,更新按鈕的可見性如果該按鈕存在,並在OnApplyTemplate()中添加一行以更新實際按鈕。那麼它也可以用作綁定的目標。

更新

這就是你如何做到這一點。這是正確的方法。

private Button _compactOverlayButton; 

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

    _compactOverlayButton = GetTemplateChild("CompactOverlayButton") as Button; 

    // Update actual button visibility to match whatever the dependency property value 
    // is, in case XAML gave us a value for it already. 
    OnIsCompactOverlayButtonVisibleChanged(); 

    _compactOverlayButton.Click += CompactOverlayButton_Click; 

    // Secondly, just in case something in the XAML may change the button's visibility, 
    // put a watch on the property and update our dependency property to match when that 
    // changes. 
    var dpd = DependencyPropertyDescriptor.FromProperty(Button.VisibilityProperty, typeof(Button)); 
    dpd.AddValueChanged(_compactOverlayButton, CompactOverlayButton_VisibilityChanged); 
} 

protected void CompactOverlayButton_VisibilityChanged(object sender, EventArgs args) 
{ 
    IsCompactOverlayButtonVisible = _compactOverlayButton.Visibility == Visibility.Visible; 
} 

private void CompactOverlayButton_Click(object sender, RoutedEventArgs e) 
{ 
    // ...whatever 
} 

#region IsCompactOverlayButtonVisible Property 
public bool IsCompactOverlayButtonVisible 
{ 
    get { return (bool)GetValue(IsCompactOverlayButtonVisibleProperty); } 
    set { SetValue(IsCompactOverlayButtonVisibleProperty, value); } 
} 

public static readonly DependencyProperty IsCompactOverlayButtonVisibleProperty = 
    DependencyProperty.Register(nameof(IsCompactOverlayButtonVisible), typeof(bool), typeof(CustomMediaTransportControls), 
     new FrameworkPropertyMetadata(true, 
             FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
             IsCompactOverlayButtonVisible_PropertyChanged)); 

protected static void IsCompactOverlayButtonVisible_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    // It's a hassle to do stuff in a static method, so my dependency property 
    // snippet just creates a private instance method and calls it from the 
    // static handler. 
    (d as CustomMediaTransportControls).OnIsCompactOverlayButtonVisibleChanged(); 
} 

private void OnIsCompactOverlayButtonVisibleChanged() 
{ 
    if (_compactOverlayButton != null) 
    { 
     // If the existing value is the same as the new value, this is a no-op 
     _compactOverlayButton.Visibility = 
      IsCompactOverlayButtonVisible 
       ? Visibility.Visible 
       : Visibility.Collapsed; 
    } 
} 
#endregion IsCompactOverlayButtonVisible Property 
+0

如何給'PropertyChanged'處理程序?你能否用'PropertyChanged'更新你的代碼。 –

+0

@VijayNirmal你在這裏工作的控制類的名字是什麼? –

+0

'CustomMediaTransportControls' –