Loading a XAML file related to a control programmatically?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












I'm trying to have a custom WPF control whose content is defined in XAML but avoiding the use of a UserControl. This is because a UserControl makes it impossible to add x:Name to its content: https://stackoverflow.com/questions/751325/how-to-create-a-wpf-usercontrol-with-named-content/3413382



My files are laid out like this:



.
│ App.config
│ App.xaml
│ App.xaml.cs
│ MainWindow.xaml
│ MainWindow.xaml.cs
│ WpfScratch.csproj
│
├───bin
│ ├───Debug
│ │ │ WpfScratch.exe
│ │ │ WpfScratch.exe.config
│ │ │ WpfScratch.pdb
│ │ │
│ │ └───Controls
│ └───Release
├───Controls
. MyPanel.cs
. MyPanel.xaml


and the source of the relevant ones is:



MyPanel.cs



public class MyPanel : Control

static MyPanel()

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyPanel), new FrameworkPropertyMetadata(typeof(MyPanel)));


public MyPanel()

var templateUri = new Uri("/WpfScratch;component/Controls/MyPanel.xaml", UriKind.Relative);
Template = (ControlTemplate) Application.LoadComponent(templateUri);


public static readonly DependencyProperty BodyProperty = DependencyProperty.Register("Body", typeof(object), typeof(MyPanel), new PropertyMetadata(default(object)));

public object Body

get => GetValue(BodyProperty);
set => SetValue(BodyProperty, value);


public static readonly DependencyProperty FooterProperty = DependencyProperty.Register("Footer", typeof(object), typeof(MyPanel), new PropertyMetadata(default(object)));

public object Footer

get => GetValue(FooterProperty);
set => SetValue(FooterProperty, value);




MyPanel.xaml



<ControlTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfScratch.Controls"
TargetType="local:MyPanel" >
<DockPanel LastChildFill="True" x:Name="Content">
<Border BorderThickness="2"
BorderBrush="Aqua"
DockPanel.Dock="Bottom">
<ContentPresenter x:Name="Footer"
Content="Binding Footer, RelativeSource=RelativeSource TemplatedParent"
Margin="0, 10" />
</Border>
<Border BorderThickness="2"
BorderBrush="Magenta">
<ContentPresenter x:Name="Body"
Content="Binding Body, RelativeSource=RelativeSource TemplatedParent" />
</Border>
</DockPanel>
</ControlTemplate>


MainWindow.xaml



<Window x:Class="WpfScratch.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfScratch"
xmlns:controls="clr-namespace:WpfScratch.Controls"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<controls:MyPanel x:Name="HelloWorldPanel">
<controls:MyPanel.Body>
<Label x:Name="HelloLabel">Hello!</Label>
</controls:MyPanel.Body>
<controls:MyPanel.Footer>
<Label x:Name="WorldLabel">World!</Label>
</controls:MyPanel.Footer>
</controls:MyPanel>
</Window>



My main concern is the loading of the XAML file, i.e.:



 var templateUri = new Uri("/WpfScratch;component/Controls/MyPanel.xaml", UriKind.Relative);
Template = (ControlTemplate) Application.LoadComponent(templateUri);


  1. Is Application.Load() the way to go? UWP seems to deprecate it in favour of XAMLReader.Load(), but I'm not sure how I would get the correct stream for that. I tried digging into the sources of Application.LoadComponent and there's some logic involved with processing pack URIs

  2. The URI is a hardcoded mouthful and seems not very resilient to refactoring. Is there a terse way of saying "hey my XAML file is right next to this one"?






share|improve this question



















  • I can't see where the name is being used. Am I overlooking something? Is it used in code which you haven't included in the question?
    – Peter Taylor
    Jul 30 at 11:01










  • @Peter - which name?
    – millimoose
    Jul 30 at 11:03










  • Any of them. You say that the reason for avoiding UserControl is that it prevents you using names, but I can't see why any of the names in the code is actually necessary. All of the binding seems to be to properties rather than elements.
    – Peter Taylor
    Jul 30 at 11:06











  • @PeterTaylor - code clarity and being able to navigate the visual tree easier when debugging
    – millimoose
    Jul 30 at 11:07










  • And yes, obviously it would be useful if I needed to identify the control in codebehind, but that’s not my use case yet and I was motivated by the previous reasons to look into this, since it’s a vexing restriction with a confusing error message
    – millimoose
    Jul 30 at 11:08

















up vote
4
down vote

favorite












I'm trying to have a custom WPF control whose content is defined in XAML but avoiding the use of a UserControl. This is because a UserControl makes it impossible to add x:Name to its content: https://stackoverflow.com/questions/751325/how-to-create-a-wpf-usercontrol-with-named-content/3413382



My files are laid out like this:



.
│ App.config
│ App.xaml
│ App.xaml.cs
│ MainWindow.xaml
│ MainWindow.xaml.cs
│ WpfScratch.csproj
│
├───bin
│ ├───Debug
│ │ │ WpfScratch.exe
│ │ │ WpfScratch.exe.config
│ │ │ WpfScratch.pdb
│ │ │
│ │ └───Controls
│ └───Release
├───Controls
. MyPanel.cs
. MyPanel.xaml


and the source of the relevant ones is:



MyPanel.cs



public class MyPanel : Control

static MyPanel()

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyPanel), new FrameworkPropertyMetadata(typeof(MyPanel)));


public MyPanel()

var templateUri = new Uri("/WpfScratch;component/Controls/MyPanel.xaml", UriKind.Relative);
Template = (ControlTemplate) Application.LoadComponent(templateUri);


public static readonly DependencyProperty BodyProperty = DependencyProperty.Register("Body", typeof(object), typeof(MyPanel), new PropertyMetadata(default(object)));

public object Body

get => GetValue(BodyProperty);
set => SetValue(BodyProperty, value);


public static readonly DependencyProperty FooterProperty = DependencyProperty.Register("Footer", typeof(object), typeof(MyPanel), new PropertyMetadata(default(object)));

public object Footer

get => GetValue(FooterProperty);
set => SetValue(FooterProperty, value);




MyPanel.xaml



<ControlTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfScratch.Controls"
TargetType="local:MyPanel" >
<DockPanel LastChildFill="True" x:Name="Content">
<Border BorderThickness="2"
BorderBrush="Aqua"
DockPanel.Dock="Bottom">
<ContentPresenter x:Name="Footer"
Content="Binding Footer, RelativeSource=RelativeSource TemplatedParent"
Margin="0, 10" />
</Border>
<Border BorderThickness="2"
BorderBrush="Magenta">
<ContentPresenter x:Name="Body"
Content="Binding Body, RelativeSource=RelativeSource TemplatedParent" />
</Border>
</DockPanel>
</ControlTemplate>


MainWindow.xaml



<Window x:Class="WpfScratch.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfScratch"
xmlns:controls="clr-namespace:WpfScratch.Controls"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<controls:MyPanel x:Name="HelloWorldPanel">
<controls:MyPanel.Body>
<Label x:Name="HelloLabel">Hello!</Label>
</controls:MyPanel.Body>
<controls:MyPanel.Footer>
<Label x:Name="WorldLabel">World!</Label>
</controls:MyPanel.Footer>
</controls:MyPanel>
</Window>



My main concern is the loading of the XAML file, i.e.:



 var templateUri = new Uri("/WpfScratch;component/Controls/MyPanel.xaml", UriKind.Relative);
Template = (ControlTemplate) Application.LoadComponent(templateUri);


  1. Is Application.Load() the way to go? UWP seems to deprecate it in favour of XAMLReader.Load(), but I'm not sure how I would get the correct stream for that. I tried digging into the sources of Application.LoadComponent and there's some logic involved with processing pack URIs

  2. The URI is a hardcoded mouthful and seems not very resilient to refactoring. Is there a terse way of saying "hey my XAML file is right next to this one"?






share|improve this question



















  • I can't see where the name is being used. Am I overlooking something? Is it used in code which you haven't included in the question?
    – Peter Taylor
    Jul 30 at 11:01










  • @Peter - which name?
    – millimoose
    Jul 30 at 11:03










  • Any of them. You say that the reason for avoiding UserControl is that it prevents you using names, but I can't see why any of the names in the code is actually necessary. All of the binding seems to be to properties rather than elements.
    – Peter Taylor
    Jul 30 at 11:06











  • @PeterTaylor - code clarity and being able to navigate the visual tree easier when debugging
    – millimoose
    Jul 30 at 11:07










  • And yes, obviously it would be useful if I needed to identify the control in codebehind, but that’s not my use case yet and I was motivated by the previous reasons to look into this, since it’s a vexing restriction with a confusing error message
    – millimoose
    Jul 30 at 11:08













up vote
4
down vote

favorite









up vote
4
down vote

favorite











I'm trying to have a custom WPF control whose content is defined in XAML but avoiding the use of a UserControl. This is because a UserControl makes it impossible to add x:Name to its content: https://stackoverflow.com/questions/751325/how-to-create-a-wpf-usercontrol-with-named-content/3413382



My files are laid out like this:



.
│ App.config
│ App.xaml
│ App.xaml.cs
│ MainWindow.xaml
│ MainWindow.xaml.cs
│ WpfScratch.csproj
│
├───bin
│ ├───Debug
│ │ │ WpfScratch.exe
│ │ │ WpfScratch.exe.config
│ │ │ WpfScratch.pdb
│ │ │
│ │ └───Controls
│ └───Release
├───Controls
. MyPanel.cs
. MyPanel.xaml


and the source of the relevant ones is:



MyPanel.cs



public class MyPanel : Control

static MyPanel()

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyPanel), new FrameworkPropertyMetadata(typeof(MyPanel)));


public MyPanel()

var templateUri = new Uri("/WpfScratch;component/Controls/MyPanel.xaml", UriKind.Relative);
Template = (ControlTemplate) Application.LoadComponent(templateUri);


public static readonly DependencyProperty BodyProperty = DependencyProperty.Register("Body", typeof(object), typeof(MyPanel), new PropertyMetadata(default(object)));

public object Body

get => GetValue(BodyProperty);
set => SetValue(BodyProperty, value);


public static readonly DependencyProperty FooterProperty = DependencyProperty.Register("Footer", typeof(object), typeof(MyPanel), new PropertyMetadata(default(object)));

public object Footer

get => GetValue(FooterProperty);
set => SetValue(FooterProperty, value);




MyPanel.xaml



<ControlTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfScratch.Controls"
TargetType="local:MyPanel" >
<DockPanel LastChildFill="True" x:Name="Content">
<Border BorderThickness="2"
BorderBrush="Aqua"
DockPanel.Dock="Bottom">
<ContentPresenter x:Name="Footer"
Content="Binding Footer, RelativeSource=RelativeSource TemplatedParent"
Margin="0, 10" />
</Border>
<Border BorderThickness="2"
BorderBrush="Magenta">
<ContentPresenter x:Name="Body"
Content="Binding Body, RelativeSource=RelativeSource TemplatedParent" />
</Border>
</DockPanel>
</ControlTemplate>


MainWindow.xaml



<Window x:Class="WpfScratch.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfScratch"
xmlns:controls="clr-namespace:WpfScratch.Controls"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<controls:MyPanel x:Name="HelloWorldPanel">
<controls:MyPanel.Body>
<Label x:Name="HelloLabel">Hello!</Label>
</controls:MyPanel.Body>
<controls:MyPanel.Footer>
<Label x:Name="WorldLabel">World!</Label>
</controls:MyPanel.Footer>
</controls:MyPanel>
</Window>



My main concern is the loading of the XAML file, i.e.:



 var templateUri = new Uri("/WpfScratch;component/Controls/MyPanel.xaml", UriKind.Relative);
Template = (ControlTemplate) Application.LoadComponent(templateUri);


  1. Is Application.Load() the way to go? UWP seems to deprecate it in favour of XAMLReader.Load(), but I'm not sure how I would get the correct stream for that. I tried digging into the sources of Application.LoadComponent and there's some logic involved with processing pack URIs

  2. The URI is a hardcoded mouthful and seems not very resilient to refactoring. Is there a terse way of saying "hey my XAML file is right next to this one"?






share|improve this question











I'm trying to have a custom WPF control whose content is defined in XAML but avoiding the use of a UserControl. This is because a UserControl makes it impossible to add x:Name to its content: https://stackoverflow.com/questions/751325/how-to-create-a-wpf-usercontrol-with-named-content/3413382



My files are laid out like this:



.
│ App.config
│ App.xaml
│ App.xaml.cs
│ MainWindow.xaml
│ MainWindow.xaml.cs
│ WpfScratch.csproj
│
├───bin
│ ├───Debug
│ │ │ WpfScratch.exe
│ │ │ WpfScratch.exe.config
│ │ │ WpfScratch.pdb
│ │ │
│ │ └───Controls
│ └───Release
├───Controls
. MyPanel.cs
. MyPanel.xaml


and the source of the relevant ones is:



MyPanel.cs



public class MyPanel : Control

static MyPanel()

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyPanel), new FrameworkPropertyMetadata(typeof(MyPanel)));


public MyPanel()

var templateUri = new Uri("/WpfScratch;component/Controls/MyPanel.xaml", UriKind.Relative);
Template = (ControlTemplate) Application.LoadComponent(templateUri);


public static readonly DependencyProperty BodyProperty = DependencyProperty.Register("Body", typeof(object), typeof(MyPanel), new PropertyMetadata(default(object)));

public object Body

get => GetValue(BodyProperty);
set => SetValue(BodyProperty, value);


public static readonly DependencyProperty FooterProperty = DependencyProperty.Register("Footer", typeof(object), typeof(MyPanel), new PropertyMetadata(default(object)));

public object Footer

get => GetValue(FooterProperty);
set => SetValue(FooterProperty, value);




MyPanel.xaml



<ControlTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfScratch.Controls"
TargetType="local:MyPanel" >
<DockPanel LastChildFill="True" x:Name="Content">
<Border BorderThickness="2"
BorderBrush="Aqua"
DockPanel.Dock="Bottom">
<ContentPresenter x:Name="Footer"
Content="Binding Footer, RelativeSource=RelativeSource TemplatedParent"
Margin="0, 10" />
</Border>
<Border BorderThickness="2"
BorderBrush="Magenta">
<ContentPresenter x:Name="Body"
Content="Binding Body, RelativeSource=RelativeSource TemplatedParent" />
</Border>
</DockPanel>
</ControlTemplate>


MainWindow.xaml



<Window x:Class="WpfScratch.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfScratch"
xmlns:controls="clr-namespace:WpfScratch.Controls"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<controls:MyPanel x:Name="HelloWorldPanel">
<controls:MyPanel.Body>
<Label x:Name="HelloLabel">Hello!</Label>
</controls:MyPanel.Body>
<controls:MyPanel.Footer>
<Label x:Name="WorldLabel">World!</Label>
</controls:MyPanel.Footer>
</controls:MyPanel>
</Window>



My main concern is the loading of the XAML file, i.e.:



 var templateUri = new Uri("/WpfScratch;component/Controls/MyPanel.xaml", UriKind.Relative);
Template = (ControlTemplate) Application.LoadComponent(templateUri);


  1. Is Application.Load() the way to go? UWP seems to deprecate it in favour of XAMLReader.Load(), but I'm not sure how I would get the correct stream for that. I tried digging into the sources of Application.LoadComponent and there's some logic involved with processing pack URIs

  2. The URI is a hardcoded mouthful and seems not very resilient to refactoring. Is there a terse way of saying "hey my XAML file is right next to this one"?








share|improve this question










share|improve this question




share|improve this question









asked Jul 30 at 8:51









millimoose

25827




25827











  • I can't see where the name is being used. Am I overlooking something? Is it used in code which you haven't included in the question?
    – Peter Taylor
    Jul 30 at 11:01










  • @Peter - which name?
    – millimoose
    Jul 30 at 11:03










  • Any of them. You say that the reason for avoiding UserControl is that it prevents you using names, but I can't see why any of the names in the code is actually necessary. All of the binding seems to be to properties rather than elements.
    – Peter Taylor
    Jul 30 at 11:06











  • @PeterTaylor - code clarity and being able to navigate the visual tree easier when debugging
    – millimoose
    Jul 30 at 11:07










  • And yes, obviously it would be useful if I needed to identify the control in codebehind, but that’s not my use case yet and I was motivated by the previous reasons to look into this, since it’s a vexing restriction with a confusing error message
    – millimoose
    Jul 30 at 11:08

















  • I can't see where the name is being used. Am I overlooking something? Is it used in code which you haven't included in the question?
    – Peter Taylor
    Jul 30 at 11:01










  • @Peter - which name?
    – millimoose
    Jul 30 at 11:03










  • Any of them. You say that the reason for avoiding UserControl is that it prevents you using names, but I can't see why any of the names in the code is actually necessary. All of the binding seems to be to properties rather than elements.
    – Peter Taylor
    Jul 30 at 11:06











  • @PeterTaylor - code clarity and being able to navigate the visual tree easier when debugging
    – millimoose
    Jul 30 at 11:07










  • And yes, obviously it would be useful if I needed to identify the control in codebehind, but that’s not my use case yet and I was motivated by the previous reasons to look into this, since it’s a vexing restriction with a confusing error message
    – millimoose
    Jul 30 at 11:08
















I can't see where the name is being used. Am I overlooking something? Is it used in code which you haven't included in the question?
– Peter Taylor
Jul 30 at 11:01




I can't see where the name is being used. Am I overlooking something? Is it used in code which you haven't included in the question?
– Peter Taylor
Jul 30 at 11:01












@Peter - which name?
– millimoose
Jul 30 at 11:03




@Peter - which name?
– millimoose
Jul 30 at 11:03












Any of them. You say that the reason for avoiding UserControl is that it prevents you using names, but I can't see why any of the names in the code is actually necessary. All of the binding seems to be to properties rather than elements.
– Peter Taylor
Jul 30 at 11:06





Any of them. You say that the reason for avoiding UserControl is that it prevents you using names, but I can't see why any of the names in the code is actually necessary. All of the binding seems to be to properties rather than elements.
– Peter Taylor
Jul 30 at 11:06













@PeterTaylor - code clarity and being able to navigate the visual tree easier when debugging
– millimoose
Jul 30 at 11:07




@PeterTaylor - code clarity and being able to navigate the visual tree easier when debugging
– millimoose
Jul 30 at 11:07












And yes, obviously it would be useful if I needed to identify the control in codebehind, but that’s not my use case yet and I was motivated by the previous reasons to look into this, since it’s a vexing restriction with a confusing error message
– millimoose
Jul 30 at 11:08





And yes, obviously it would be useful if I needed to identify the control in codebehind, but that’s not my use case yet and I was motivated by the previous reasons to look into this, since it’s a vexing restriction with a confusing error message
– millimoose
Jul 30 at 11:08











1 Answer
1






active

oldest

votes

















up vote
5
down vote



accepted










The conventional way of attaching default template to custom control is to specify default style inside a special resource dictionary. For this approach to work three conditions should be met:



1) Resource dictionary should be located at Themes/Generic.xaml. There you should place a default style for your custom control (that in turn should set Template property to default value).



2) Your AssemblyInfo.cs file should contain ThemeInfoAttribute.



3) Your custom control should override default style key inside a static constructor, using DefaultStyleKeyProperty.OverrideMetadata method.



Alternatively, if you are not planning on reusing your custom control, you can just drop the default style into App.xaml resources and avoid above shenanigans.



For more info see: https://michaelscodingspot.com/2016/12/24/explicit-implicit-and-default-styles-in-wpf/






share|improve this answer





















  • Will this work is this control is in a subproject that’s referenced by the main app’s project in a solution? That is, is the theme tied to the assembly rather than the app itself?
    – millimoose
    Jul 30 at 11:06






  • 2




    @millimoose, the three points are for using it as a subproject. The line beginning "Alternatively" is the simpler approach which suffices if you just want to tie the theme to the app.
    – Peter Taylor
    Jul 30 at 11:07










  • @millimoose, yes, first approach will work "out of the box": you will be able to use your custom controls the same way you use default ones - just by referencing them in your xaml. Second approach will technically work as well, but you would have to manually specify path to resource dictionary inside App.xaml every time you create a new application that depends on your sub-project. For that reason I wouldn't recommend using it across different assemblies.
    – Nikita B
    Jul 30 at 11:17










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200572%2floading-a-xaml-file-related-to-a-control-programmatically%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
5
down vote



accepted










The conventional way of attaching default template to custom control is to specify default style inside a special resource dictionary. For this approach to work three conditions should be met:



1) Resource dictionary should be located at Themes/Generic.xaml. There you should place a default style for your custom control (that in turn should set Template property to default value).



2) Your AssemblyInfo.cs file should contain ThemeInfoAttribute.



3) Your custom control should override default style key inside a static constructor, using DefaultStyleKeyProperty.OverrideMetadata method.



Alternatively, if you are not planning on reusing your custom control, you can just drop the default style into App.xaml resources and avoid above shenanigans.



For more info see: https://michaelscodingspot.com/2016/12/24/explicit-implicit-and-default-styles-in-wpf/






share|improve this answer





















  • Will this work is this control is in a subproject that’s referenced by the main app’s project in a solution? That is, is the theme tied to the assembly rather than the app itself?
    – millimoose
    Jul 30 at 11:06






  • 2




    @millimoose, the three points are for using it as a subproject. The line beginning "Alternatively" is the simpler approach which suffices if you just want to tie the theme to the app.
    – Peter Taylor
    Jul 30 at 11:07










  • @millimoose, yes, first approach will work "out of the box": you will be able to use your custom controls the same way you use default ones - just by referencing them in your xaml. Second approach will technically work as well, but you would have to manually specify path to resource dictionary inside App.xaml every time you create a new application that depends on your sub-project. For that reason I wouldn't recommend using it across different assemblies.
    – Nikita B
    Jul 30 at 11:17














up vote
5
down vote



accepted










The conventional way of attaching default template to custom control is to specify default style inside a special resource dictionary. For this approach to work three conditions should be met:



1) Resource dictionary should be located at Themes/Generic.xaml. There you should place a default style for your custom control (that in turn should set Template property to default value).



2) Your AssemblyInfo.cs file should contain ThemeInfoAttribute.



3) Your custom control should override default style key inside a static constructor, using DefaultStyleKeyProperty.OverrideMetadata method.



Alternatively, if you are not planning on reusing your custom control, you can just drop the default style into App.xaml resources and avoid above shenanigans.



For more info see: https://michaelscodingspot.com/2016/12/24/explicit-implicit-and-default-styles-in-wpf/






share|improve this answer





















  • Will this work is this control is in a subproject that’s referenced by the main app’s project in a solution? That is, is the theme tied to the assembly rather than the app itself?
    – millimoose
    Jul 30 at 11:06






  • 2




    @millimoose, the three points are for using it as a subproject. The line beginning "Alternatively" is the simpler approach which suffices if you just want to tie the theme to the app.
    – Peter Taylor
    Jul 30 at 11:07










  • @millimoose, yes, first approach will work "out of the box": you will be able to use your custom controls the same way you use default ones - just by referencing them in your xaml. Second approach will technically work as well, but you would have to manually specify path to resource dictionary inside App.xaml every time you create a new application that depends on your sub-project. For that reason I wouldn't recommend using it across different assemblies.
    – Nikita B
    Jul 30 at 11:17












up vote
5
down vote



accepted







up vote
5
down vote



accepted






The conventional way of attaching default template to custom control is to specify default style inside a special resource dictionary. For this approach to work three conditions should be met:



1) Resource dictionary should be located at Themes/Generic.xaml. There you should place a default style for your custom control (that in turn should set Template property to default value).



2) Your AssemblyInfo.cs file should contain ThemeInfoAttribute.



3) Your custom control should override default style key inside a static constructor, using DefaultStyleKeyProperty.OverrideMetadata method.



Alternatively, if you are not planning on reusing your custom control, you can just drop the default style into App.xaml resources and avoid above shenanigans.



For more info see: https://michaelscodingspot.com/2016/12/24/explicit-implicit-and-default-styles-in-wpf/






share|improve this answer













The conventional way of attaching default template to custom control is to specify default style inside a special resource dictionary. For this approach to work three conditions should be met:



1) Resource dictionary should be located at Themes/Generic.xaml. There you should place a default style for your custom control (that in turn should set Template property to default value).



2) Your AssemblyInfo.cs file should contain ThemeInfoAttribute.



3) Your custom control should override default style key inside a static constructor, using DefaultStyleKeyProperty.OverrideMetadata method.



Alternatively, if you are not planning on reusing your custom control, you can just drop the default style into App.xaml resources and avoid above shenanigans.



For more info see: https://michaelscodingspot.com/2016/12/24/explicit-implicit-and-default-styles-in-wpf/







share|improve this answer













share|improve this answer



share|improve this answer











answered Jul 30 at 10:51









Nikita B

12.3k11551




12.3k11551











  • Will this work is this control is in a subproject that’s referenced by the main app’s project in a solution? That is, is the theme tied to the assembly rather than the app itself?
    – millimoose
    Jul 30 at 11:06






  • 2




    @millimoose, the three points are for using it as a subproject. The line beginning "Alternatively" is the simpler approach which suffices if you just want to tie the theme to the app.
    – Peter Taylor
    Jul 30 at 11:07










  • @millimoose, yes, first approach will work "out of the box": you will be able to use your custom controls the same way you use default ones - just by referencing them in your xaml. Second approach will technically work as well, but you would have to manually specify path to resource dictionary inside App.xaml every time you create a new application that depends on your sub-project. For that reason I wouldn't recommend using it across different assemblies.
    – Nikita B
    Jul 30 at 11:17
















  • Will this work is this control is in a subproject that’s referenced by the main app’s project in a solution? That is, is the theme tied to the assembly rather than the app itself?
    – millimoose
    Jul 30 at 11:06






  • 2




    @millimoose, the three points are for using it as a subproject. The line beginning "Alternatively" is the simpler approach which suffices if you just want to tie the theme to the app.
    – Peter Taylor
    Jul 30 at 11:07










  • @millimoose, yes, first approach will work "out of the box": you will be able to use your custom controls the same way you use default ones - just by referencing them in your xaml. Second approach will technically work as well, but you would have to manually specify path to resource dictionary inside App.xaml every time you create a new application that depends on your sub-project. For that reason I wouldn't recommend using it across different assemblies.
    – Nikita B
    Jul 30 at 11:17















Will this work is this control is in a subproject that’s referenced by the main app’s project in a solution? That is, is the theme tied to the assembly rather than the app itself?
– millimoose
Jul 30 at 11:06




Will this work is this control is in a subproject that’s referenced by the main app’s project in a solution? That is, is the theme tied to the assembly rather than the app itself?
– millimoose
Jul 30 at 11:06




2




2




@millimoose, the three points are for using it as a subproject. The line beginning "Alternatively" is the simpler approach which suffices if you just want to tie the theme to the app.
– Peter Taylor
Jul 30 at 11:07




@millimoose, the three points are for using it as a subproject. The line beginning "Alternatively" is the simpler approach which suffices if you just want to tie the theme to the app.
– Peter Taylor
Jul 30 at 11:07












@millimoose, yes, first approach will work "out of the box": you will be able to use your custom controls the same way you use default ones - just by referencing them in your xaml. Second approach will technically work as well, but you would have to manually specify path to resource dictionary inside App.xaml every time you create a new application that depends on your sub-project. For that reason I wouldn't recommend using it across different assemblies.
– Nikita B
Jul 30 at 11:17




@millimoose, yes, first approach will work "out of the box": you will be able to use your custom controls the same way you use default ones - just by referencing them in your xaml. Second approach will technically work as well, but you would have to manually specify path to resource dictionary inside App.xaml every time you create a new application that depends on your sub-project. For that reason I wouldn't recommend using it across different assemblies.
– Nikita B
Jul 30 at 11:17












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200572%2floading-a-xaml-file-related-to-a-control-programmatically%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation