Pulling controls from resources
-
Is it possible to put controls in app resources and use then as elements inside a StackPanel ? A bit of context: I have a UserControl which I use like this:
SELECT blablabla select rarara etc etc etc
Each local:FeatureSelectionControl fetches a list of values from a database and lets the user choose one of more values. I will need to use the same FeatureSelectionControls (i.e. with the same Table/Label/SelectStatement combination) in a dozen of dialog boxes. Since the SQL may change I don't want to duplicate the elements all over. So I thought I'd put them in an application resource. But first let's try with a window resource:
SELECT blablabla
Now how do I put the control in the StackPanel's collection of children ? IntelliSense didn't suggest a element but I still tried:
When I run it, I get a "first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll - Additional information: Stack empty.". However, the preview in the Designer is just fine. Does this approach has any chance of working ? What am I doing wrong ? If it works, will I get a single instance of a control (as identified by the same key) shared between my dialogs ? Or is a new instance created each time I pull from the resources ? What are the alternatives (I see one
-
Is it possible to put controls in app resources and use then as elements inside a StackPanel ? A bit of context: I have a UserControl which I use like this:
SELECT blablabla select rarara etc etc etc
Each local:FeatureSelectionControl fetches a list of values from a database and lets the user choose one of more values. I will need to use the same FeatureSelectionControls (i.e. with the same Table/Label/SelectStatement combination) in a dozen of dialog boxes. Since the SQL may change I don't want to duplicate the elements all over. So I thought I'd put them in an application resource. But first let's try with a window resource:
SELECT blablabla
Now how do I put the control in the StackPanel's collection of children ? IntelliSense didn't suggest a element but I still tried:
When I run it, I get a "first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll - Additional information: Stack empty.". However, the preview in the Designer is just fine. Does this approach has any chance of working ? What am I doing wrong ? If it works, will I get a single instance of a control (as identified by the same key) shared between my dialogs ? Or is a new instance created each time I pull from the resources ? What are the alternatives (I see one
Jean-Louis Leroy wrote:
If it works, will I get a single instance of a control (as identified by the same key) shared between my dialogs ? Or is a new instance created each time I pull from the resources ?
Neither... Each defined resource is a single instance, but it gets defined once for every window. So each window gets exactly one instance. This means you can use it once per window, but no more than that (Because a UI element can only have one parent).
Jean-Louis Leroy wrote:
When I run it, I get a "first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll - Additional information: Stack empty.".
I would suggest looking at the call stack, to get a little more information about that exception. Exactly what was it trying to do when it hit that exception? Was it related to the control being in the StackPanel, or was it something inside the FeatureSelectionControl?
Jean-Louis Leroy wrote:
What are the alternatives (I see one: put the three strings in resources, not the entire control).
You could also do this by defining styles or templates. Those are intended to be reused (Unlike defining the control itself as a resource). Then, instead of putting a StaticResource directly into a StackPanel, you would do something like this:
<Style x:Key="GroupOwnerCRDSCode" TargetType="local:FeatureSelectionControl">
<Setter Property="Table" Value="GroupOwnerCRDSCode"/>
<Setter Property="Label" Value="Customer Group"/>
<Setter Property="SelectStatement">
<Setter.Value>
SELECT blablabla
</Setter.Value>
</Setter>
</Style><StackPanel ...>
<local:FeatureSelectionControl Style="{StaticResource GroupOwnerCRDSCode}"/>
</StackPanel>Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels) -
Jean-Louis Leroy wrote:
If it works, will I get a single instance of a control (as identified by the same key) shared between my dialogs ? Or is a new instance created each time I pull from the resources ?
Neither... Each defined resource is a single instance, but it gets defined once for every window. So each window gets exactly one instance. This means you can use it once per window, but no more than that (Because a UI element can only have one parent).
Jean-Louis Leroy wrote:
When I run it, I get a "first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll - Additional information: Stack empty.".
I would suggest looking at the call stack, to get a little more information about that exception. Exactly what was it trying to do when it hit that exception? Was it related to the control being in the StackPanel, or was it something inside the FeatureSelectionControl?
Jean-Louis Leroy wrote:
What are the alternatives (I see one: put the three strings in resources, not the entire control).
You could also do this by defining styles or templates. Those are intended to be reused (Unlike defining the control itself as a resource). Then, instead of putting a StaticResource directly into a StackPanel, you would do something like this:
<Style x:Key="GroupOwnerCRDSCode" TargetType="local:FeatureSelectionControl">
<Setter Property="Table" Value="GroupOwnerCRDSCode"/>
<Setter Property="Label" Value="Customer Group"/>
<Setter Property="SelectStatement">
<Setter.Value>
SELECT blablabla
</Setter.Value>
</Setter>
</Style><StackPanel ...>
<local:FeatureSelectionControl Style="{StaticResource GroupOwnerCRDSCode}"/>
</StackPanel>Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels)Thanks for the very clear explanations and the suggestion about Styles. It looks like a better idea because - if I'm not mistaken - it will allow me to set other properties like Margin etc. Out of curiosity I still took a look at the stack trace in my control-in-resource approach. Here it is:
PresentationFramework.dll!System.Windows.Markup.XamlParseException.ThrowException(string message, System.Exception innerException, int lineNumber, int linePosition, System.Uri baseUri, System.Windows.Markup.XamlObjectIds currentXamlObjectIds, System.Windows.Markup.XamlObjectIds contextXamlObjectIds, System.Type objectType) + 0x1bf bytes PresentationFramework.dll!System.Windows.Markup.XamlParseException.ThrowException(System.Windows.Markup.ParserContext parserContext, int lineNumber, int linePosition, string message, System.Exception innerException) + 0x58 bytes PresentationFramework.dll!System.Windows.Markup.BamlRecordReader.ReadRecord(System.Windows.Markup.BamlRecord bamlRecord) + 0x75f bytes PresentationFramework.dll!System.Windows.Markup.BamlRecordReader.Read(bool singleRecord = false) + 0x1c bytes PresentationFramework.dll!System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment() + 0xc9 bytes PresentationFramework.dll!System.Windows.Markup.TreeBuilder.Parse() + 0xf bytes PresentationFramework.dll!System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, object parent, bool closeStream) + 0xc7 bytes PresentationFramework.dll!System.Windows.Application.LoadComponent(object component, System.Uri resourceLocator) + 0x16e bytes
CRRT.exe!CRRT.WindowCounterpartyGroupRiskReview.InitializeComponent() Line 1 + 0xb bytes C#
CRRT.exe!CRRT.WindowCounterpartyGroupRiskReview.WindowCounterpartyGroupRiskReview() Line 29 + 0x8 bytes C# -
Thanks for the very clear explanations and the suggestion about Styles. It looks like a better idea because - if I'm not mistaken - it will allow me to set other properties like Margin etc. Out of curiosity I still took a look at the stack trace in my control-in-resource approach. Here it is:
PresentationFramework.dll!System.Windows.Markup.XamlParseException.ThrowException(string message, System.Exception innerException, int lineNumber, int linePosition, System.Uri baseUri, System.Windows.Markup.XamlObjectIds currentXamlObjectIds, System.Windows.Markup.XamlObjectIds contextXamlObjectIds, System.Type objectType) + 0x1bf bytes PresentationFramework.dll!System.Windows.Markup.XamlParseException.ThrowException(System.Windows.Markup.ParserContext parserContext, int lineNumber, int linePosition, string message, System.Exception innerException) + 0x58 bytes PresentationFramework.dll!System.Windows.Markup.BamlRecordReader.ReadRecord(System.Windows.Markup.BamlRecord bamlRecord) + 0x75f bytes PresentationFramework.dll!System.Windows.Markup.BamlRecordReader.Read(bool singleRecord = false) + 0x1c bytes PresentationFramework.dll!System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment() + 0xc9 bytes PresentationFramework.dll!System.Windows.Markup.TreeBuilder.Parse() + 0xf bytes PresentationFramework.dll!System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, object parent, bool closeStream) + 0xc7 bytes PresentationFramework.dll!System.Windows.Application.LoadComponent(object component, System.Uri resourceLocator) + 0x16e bytes
CRRT.exe!CRRT.WindowCounterpartyGroupRiskReview.InitializeComponent() Line 1 + 0xb bytes C#
CRRT.exe!CRRT.WindowCounterpartyGroupRiskReview.WindowCounterpartyGroupRiskReview() Line 29 + 0x8 bytes C#Ugh, typical unhelpful Xaml/Baml traces... Really wish Microsoft would put some useful information in there. The only strategy I know for errors like that, is to just keep commenting out bits of the XAML until it runs successfully, and then narrowing it down from there.
Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels) -
Ugh, typical unhelpful Xaml/Baml traces... Really wish Microsoft would put some useful information in there. The only strategy I know for errors like that, is to just keep commenting out bits of the XAML until it runs successfully, and then narrowing it down from there.
Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels)Ian Shlasko wrote:
Ugh, typical unhelpful Xaml/Baml traces... Really wish Microsoft would put some useful information in there.
Really wish Microsoft would give the source code like they used to for the CRT :laugh: I'm very happy with the Style-based solution, thanks.