如何在模板中获取ContentControl子项

时间:2018-06-14 20:20:08

标签: c# wpf

我花了几个小时进行搜索和测试,无法让它发挥作用。我想有一个UserControl,它公开一个模板来填充UserControl的一部分。我通过创建ContentTemplate(或DataTemplate?)类型的DependencyProperty来实现它。然后我像这样显示它

<ContentControl x:Name="PlayerContent" ContentTemplate="{Binding PlayerTemplate, ElementName=W}" />

现在的问题是,当我使用UserControl时,我无法在模板中设置元素名称。

<local:MediaPlayerWpf x:Name="PlayerUI" Height="auto" Width="auto">
    <local:MediaPlayerWpf.PlayerTemplate>
        <ControlTemplate>
            <WindowsFormsHost x:Name="Host" Focusable="False" />
        </ControlTemplate>
    </local:MediaPlayerWpf.PlayerTemplate>
</local:MediaPlayerWpf>

抛出

  

无法设置名称属性值&#39;主机&#39;在元素上   &#39; WindowsFormsHost&#39 ;. &#39; WindowsFormsHost&#39;是在   元素&#39; MediaPlayerWpf&#39;的范围,已经注册了名称   当它在另一个范围内定义时。

因此,我无法访问模板中定义的控件。我还发现无法访问ContentControl中显示的子项的根目录。

如何访问&#34;主机&#34;模板中定义的控件?

1 个答案:

答案 0 :(得分:0)

似乎我们不能在UserControl中以这种方式使用模板。我不知道是否有解决办法。

我最终采取了不同的方法。我公开了一个属性来设置内容。

public static DependencyProperty HostProperty = DependencyProperty.Register("Host", typeof(PlayerBase), typeof(MediaPlayerWpf), new PropertyMetadata(null, OnHostChanged));
public PlayerBase Host { get => (PlayerBase)base.GetValue(HostProperty); set => base.SetValue(HostProperty, value); }
private static void OnHostChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    MediaPlayerWpf P = d as MediaPlayerWpf;
    if (e.OldValue != null)
        P.HostGrid.Children.Remove(e.OldValue as PlayerBase);
    if (e.NewValue != null) {
        P.HostGrid.Children.Add(e.NewValue as PlayerBase);
        P.UI.PlayerHost = e.NewValue as PlayerBase;
    }
}

然后在使用该类的代码隐藏中,我将其设置为

Player.Host = new MpvMediaPlayerHost();

至少它正在发挥作用。

编辑:更好的解决方案是从用户控制切换到自定义控件。我仍然应用上面的解决方案,并切换到自定义控件允许我在派生类的构造函数中设置主机。