- 您应该定义
DependencyProperty
属性而不是常规属性。
- 派生自
ContentControl
而不是UserControl
.
- 将您的 XAML 放在 Themes/Generic.xaml 中的
Style/Setter/Property="Template" Value="...
. 如果您使用 Templated Control VS item 模板创建控件,它会自动发生。
- 使用 TemplateBinding 将内部模板元素的属性绑定到您的控件属性。
FindName 可能无法跨名称范围工作。我从不使用它。
原谅错别字。在手机上打字。
这是一个解决方案:
创建模板化控件(也称为自定义控件 - 不要与 UserControl 混淆)并将其修改为派生自ContentControl
而不是Control
:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
// The Templated Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234235
namespace App124
{
[TemplatePart(Name = "_OK", Type = typeof(Button))]
[TemplatePart(Name = "_Cancel", Type = typeof(Button))]
public sealed class BannerPanel : ContentControl
{
#region Title
/// <summary>
/// Title Dependency Property
/// </summary>
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register(
"Title",
typeof(string),
typeof(BannerPanel),
new PropertyMetadata(null, OnTitleChanged));
/// <summary>
/// Gets or sets the Title property. This dependency property
/// indicates ....
/// </summary>
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
/// <summary>
/// Handles changes to the Title property.
/// </summary>
/// <param name="d">
/// The <see cref="DependencyObject"/> on which
/// the property has changed value.
/// </param>
/// <param name="e">
/// Event data that is issued by any event that
/// tracks changes to the effective value of this property.
/// </param>
private static void OnTitleChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (BannerPanel)d;
string oldTitle = (string)e.OldValue;
string newTitle = target.Title;
target.OnTitleChanged(oldTitle, newTitle);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes
/// to the Title property.
/// </summary>
/// <param name="oldTitle">The old Title value</param>
/// <param name="newTitle">The new Title value</param>
private void OnTitleChanged(
string oldTitle, string newTitle)
{
}
#endregion
#region OKVisibility
/// <summary>
/// OKVisibility Dependency Property
/// </summary>
public static readonly DependencyProperty OKVisibilityProperty =
DependencyProperty.Register(
"OKVisibility",
typeof(Visibility),
typeof(BannerPanel),
new PropertyMetadata(Visibility.Visible, OnOKVisibilityChanged));
/// <summary>
/// Gets or sets the OKVisibility property. This dependency property
/// indicates ....
/// </summary>
public Visibility OKVisibility
{
get { return (Visibility)GetValue(OKVisibilityProperty); }
set { SetValue(OKVisibilityProperty, value); }
}
/// <summary>
/// Handles changes to the OKVisibility property.
/// </summary>
/// <param name="d">
/// The <see cref="DependencyObject"/> on which
/// the property has changed value.
/// </param>
/// <param name="e">
/// Event data that is issued by any event that
/// tracks changes to the effective value of this property.
/// </param>
private static void OnOKVisibilityChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (BannerPanel)d;
Visibility oldOKVisibility = (Visibility)e.OldValue;
Visibility newOKVisibility = target.OKVisibility;
target.OnOKVisibilityChanged(oldOKVisibility, newOKVisibility);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes
/// to the OKVisibility property.
/// </summary>
/// <param name="oldOKVisibility">The old OKVisibility value</param>
/// <param name="newOKVisibility">The new OKVisibility value</param>
private void OnOKVisibilityChanged(
Visibility oldOKVisibility, Visibility newOKVisibility)
{
}
#endregion
#region CancelVisibility
/// <summary>
/// CancelVisibility Dependency Property
/// </summary>
public static readonly DependencyProperty CancelVisibilityProperty =
DependencyProperty.Register(
"CancelVisibility",
typeof(Visibility),
typeof(BannerPanel),
new PropertyMetadata(Visibility.Visible, OnCancelVisibilityChanged));
/// <summary>
/// Gets or sets the CancelVisibility property. This dependency property
/// indicates ....
/// </summary>
public Visibility CancelVisibility
{
get { return (Visibility)GetValue(CancelVisibilityProperty); }
set { SetValue(CancelVisibilityProperty, value); }
}
/// <summary>
/// Handles changes to the CancelVisibility property.
/// </summary>
/// <param name="d">
/// The <see cref="DependencyObject"/> on which
/// the property has changed value.
/// </param>
/// <param name="e">
/// Event data that is issued by any event that
/// tracks changes to the effective value of this property.
/// </param>
private static void OnCancelVisibilityChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (BannerPanel)d;
Visibility oldCancelVisibility = (Visibility)e.OldValue;
Visibility newCancelVisibility = target.CancelVisibility;
target.OnCancelVisibilityChanged(oldCancelVisibility, newCancelVisibility);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes
/// to the CancelVisibility property.
/// </summary>
/// <param name="oldCancelVisibility">The old CancelVisibility value</param>
/// <param name="newCancelVisibility">The new CancelVisibility value</param>
private void OnCancelVisibilityChanged(
Visibility oldCancelVisibility, Visibility newCancelVisibility)
{
}
#endregion
/// <summary>
/// Fires when the Ok button is clicked
/// </summary>
public event RoutedEventHandler OkClick;
/// <summary>
/// Fires when the Cancel button is clicked
/// </summary>
public event RoutedEventHandler CancelClick;
public BannerPanel()
{
this.DefaultStyleKey = typeof(BannerPanel);
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var cancelButton = (Button)GetTemplateChild("_Cancel");
var okButton = (Button)GetTemplateChild("_OK");
cancelButton.Click += CancelClick;
okButton.Click += OkClick;
}
}
}
将Themes/Generic.xaml更新为:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App124">
<Style
TargetType="local:BannerPanel">
<Setter
Property="HorizontalContentAlignment"
Value="Left" />
<Setter
Property="VerticalContentAlignment"
Value="Top" />
<Setter
Property="Title"
Value="Title" />
<Setter
Property="OKVisibility"
Value="Visible" />
<Setter
Property="CancelVisibility"
Value="Visible" />
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="local:BannerPanel">
<Grid
Background="#BF8B8B8B">
<Grid
Height="400"
Background="#FF050A7C"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition
Height="50" />
<RowDefinition
Height="*" />
<RowDefinition
Height="50" />
</Grid.RowDefinitions>
<TextBlock
x:Name="_Title"
Text="{TemplateBinding Title}"
FontSize="30"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
<ContentPresenter
Grid.Row="1"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
<StackPanel
Orientation="Horizontal"
Grid.Row="2"
HorizontalAlignment="Center">
<Button
x:Name="_OK"
Content="OK"
Visibility="{TemplateBinding OKVisibility}"
HorizontalAlignment="Center"
FontSize="18"
Width="100"
Margin="20,0" />
<Button
x:Name="_Cancel"
Content="Cancel"
Visibility="{TemplateBinding CancelVisibility}"
HorizontalAlignment="Center"
FontSize="18"
Width="100"
Margin="20,0" />
</StackPanel>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
这是它在MainPage.xaml中的使用方式:
<Page
x:Class="App124.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App124"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid
Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<local:BannerPanel
x:Name="Banner"
Title="Terms and Policy"
CancelVisibility="Collapsed"
OkClick="OnTermsAccepted">
<ScrollViewer
Width="500">
<TextBlock
x:Name="TermsText"
Text="Terms and Conditions"
TextWrapping="Wrap"
FontSize="12" />
</ScrollViewer>
</local:BannerPanel>
</Grid>
</Page>
和MainPage.xaml.cs 后面的代码:
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace App124
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void OnTermsAccepted(object sender, RoutedEventArgs e)
{
new MessageDialog(TermsText.Text).ShowAsync();
}
}
}