简体   繁体   中英

WPF: How to access element in ResourceDictionary code behind

In my application I have a control which renders a number of blocks on a timeline view (like a calendar). One can provide a template for the blocks by giving the timeline an appropriate DataTemplate.

I would like to separate the block DataTemplate from the main timeline view, putting the block into its own XAML. As such, I've created a XAML for the Block (called Block.xaml) and wrapped the DataTemplate inside a ResourceDictionary, inside this XAML.

I've added a code behind to the XAML (called Block.xaml.cs) in which I need to access some of the elements in the block. The issue is that ResourceDictionaries seem to hide the elements from the codebehind such that I can't access them. I can't use a UserControl instead - this seems to not work.

How can I access the elements of the Block DataTemplate from the code behind?

Many thanks in advance for your help.


Block.xaml:

<ResourceDictionary x:Class="Project.Windows.MainInterface.TimelinePanel.Block" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Project.Windows.MainInterface.TimelinePanel" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:converters="clr-namespace:Project.Converters" >
<DataTemplate x:Key="ItemBlockTemplate">
    <Grid Name="BlockParent" Width="Auto" Height="Auto" MinHeight="50" ClipToBounds="True" SizeChanged="BlockParent_OnSizeChanged">
        <Border Panel.ZIndex="3" BorderBrush="{DynamicResource BackgroundGreyLight}" BorderThickness="1" CornerRadius="1" />
        <Grid Margin="1" Background="{DynamicResource BlockBackgroundGradient}" d:LayoutOverrides="Width">
            <TextBlock x:Name="blockName" Height="20" Margin="4,0,4,0" Padding="3" VerticalAlignment="Top" Panel.ZIndex="3" FontSize="10" Foreground="{DynamicResource TextLight}" Text="{Binding blockName}" TextTrimming="CharacterEllipsis" Visibility="Visible" />
            <TextBlock x:Name="Duration" Margin="0,2,4,2" Padding="0,0,3,0" HorizontalAlignment="Right" VerticalAlignment="Bottom" Panel.ZIndex="5" FontSize="10" Foreground="{DynamicResource TextLight}" Text="{Binding FormattedDuration}" ToolTip="{Binding Duration}" />
            <Grid Background="#FF0FA8FF" Opacity="0.7" />
        </Grid>
    </Grid>
</DataTemplate>

Snippet of the Timeline in the main interface:

 ...
 <timeLineTool:TimeLineControl x:Name="Timeline" Height="50" MinWidth="50" Margin="0,0,12,0" HorizontalAlignment="Left" VerticalAlignment="Top" Items="{Binding Timeline}" SnapsToDevicePixels="True" UnitSize="{Binding UnitSize}" UseLayoutRounding="True">
        <timeLineTool:TimeLineControl.ItemTemplate>
            <DataTemplate DataType="{x:Type local:BlockItemViewModel}">
                <ContentControl>
                    <ContentPresenter Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="{Binding}" ContentTemplate="{StaticResource ItemBlockTemplate}" />
                </ContentControl>
            </DataTemplate>
        </timeLineTool:TimeLineControl.ItemTemplate>
    </timeLineTool:TimeLineControl>
 ...

...If I could use a UserControl instead of a ResourceDictionary for my Block, this would solve the problem, as all elements are automatically publicly available in the code behind for usercontrols.

Sample XAML:

 <Window.Resources>
      <ControlTemplate x:Key="ResourceName" TargetType="{x:Type Label}">
          <Label  Foreground="White" Content="{iconPacks:PackIconFontAwesome plug,Height=40,Width=40}"/>
      </ControlTemplate>
 </Window.Resources>

Code behind

ControlTemplate Dictionary:

 private Dictionary<string, ControlTemplate> collection
    {
        get
        {
            Dictionary<string, ControlTemplate> controlTemplates = new Dictionary<string, ControlTemplate>();
            controlTemplates.Add("ResourceName", FindResource("ResourceName") as ControlTemplate);
            return controlTemplates;
        }
    }

Use ControlTemplate:

    Label LBDisConnect = new Label();
    LBDisConnect.Template = collection["ResourceName"];
    LoginInfo.Children.Add(LBDisConnect);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM