xaml引用包含其子元素的元素

时间:2017-06-16 21:59:29

标签: c# xml xaml uwp

我有几个页面包含相同的边框及其子元素。 每个页面都有

<Border Grid.Column="1" Style="{StaticResource InstructionBox}" x:name="staticBorder">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5*"/>
            <ColumnDefinition Width="5*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="20"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Button Style="{StaticResource OnlyContentStyle}" Grid.Row="0" Grid.Column="0"
                Click="Instruction_Click">
            <Border >
                <TextBlock Style="{StaticResource InstructionStyle}">
                </TextBlock>
            </Border>
        </Button>

        <Button Style="{StaticResource OnlyContentStyle}" Grid.Row="0" Grid.Column="1"
                Click="Logs_Click">
            <Border >
                <TextBlock Style="{StaticResource LogStyle}">
                </TextBlock>
            </Border>
        </Button>
        <Border Grid.Row="2" Grid.ColumnSpan="2" x:Name="InstructionBorder">
            <StackPanel x:Name="PanelInstructions" Style="{StaticResource InstructionTextStyle}">
            </StackPanel>
        </Border>
    </Grid>
</Border>

有没有办法在我的所有页面中引用此边框?

由于

1 个答案:

答案 0 :(得分:2)

不,没有直接的方法。 XAML仅允许元素存在于Visual Tree的单个位置。为此,您需要将边框转换为用户控件。有几种方法可以做到这一点。在下面的示例中,我使用依赖项属性为后面的用户控件代码中的第一个按钮提供可变内容。对于click事件,我建议将按钮Command绑定到ICommand实现,但是你需要为此做MVVM。此示例添加了RoutedEventHandler。

public static readonly DependencyProperty InstructionButtonContentProperty = DependencyProperty.Register(
    "InstructionButtonContent", typeof(FrameworkElement), typeof(InstructionBoxControl), new PropertyMetadata(default(FrameworkElement)));

public FrameworkElement InstructionButtonContent
{
    get { return (FrameworkElement) GetValue(InstructionButtonContentProperty); }
    set { SetValue(InstructionButtonContentProperty, value); }
}

public event RoutedEventHandler InstructionButtonClicked;

public InstructionBoxControl()
{
    InitializeComponent();
}

private void InstructionButtonClick(object sender, RoutedEventArgs e)
{
    InstructionButtonClicked?.Invoke(sender, e);
}

在大多数情况下,您可以将边框粘贴到用户控件的XAML中。然后,您需要将动态部分绑定到用户控件的DependencyProperties。您还可以将按钮的click事件调用连接到上面代码中的RoutedEventHandler。

<Border >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5*" />
            <ColumnDefinition Width="5*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="100" />
            <RowDefinition Height="20" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Button Grid.Row="0"
                Grid.Column="0"
                Click="InstructionButtonClick">
            <Border>
                <ContentPresenter Content="{Binding Path=InstructionButtonContent, RelativeSource={RelativeSource AncestorType={x:Type local:InstructionBoxControl}}}"/>
            </Border>
        </Button>

然后,您可以在任何页面上使用新的UserControl来代替边框:

<local:InstructionBoxControl InstructionButtonClicked="InstructionBoxControl_OnInstructionButtonClicked">
    <local:InstructionBoxControl.InstructionButtonContent>
        <TextBlock>Instructions</TextBlock>
    </local:InstructionBoxControl.InstructionButtonContent>
</local:InstructionBoxControl>

另一个按钮和satckpanel的工作方式应该相同。