2017-04-18 171 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' –