How to declare a decimal value in XAML? - silverlight

I'm able to declare an integer or double value in xaml. However, I can't add a decimal value. It builds ok, but then I get:
System.Windows.Markup.XamlParseException: The type 'Decimal' was not
found.
Here's the xaml code:
<UserControl.Resources>
<system:Int32 x:Key="AnIntValue">1000</system:Int32><!--Works!-->
<system:Double x:Key="ADoubleValue">1000.0</system:Double><!--Works!-->
<system:Decimal x:Key="ADecimalValue">1000.0</system:Decimal><!--Fails at runtime-->
</UserControl.Resources>
Here's how I'm declaring the system namespace:
xmlns:system="clr-namespace:System;assembly=mscorlib"
Edit: Workaround:
As Steven mentioned, adding the resource through code-behind seems to work fine:
Resources.Add("ADecimalValue", new Decimal(1000.0));
Edit: Answer:
Doing exactly the same thing in WPF seems to work fine. So I guess this is a hidden silverlight restriction. Thanks to Steven for this finding.

I have confirmed your finding that the Decimal type does not appear to work as a static resource in a UserControl's resources section. I do however see a couple workarounds that have been discussed here on StackOverflow, and that i have just personally verified to work with the Decimal type in Silverlight: Access codebehind variable in XAML
The workarounds include:
adding the resource from the code-behind (see the link above)
Referencing a property in the code behind using an "elementname" type binding
Accessing a public Decimal property on the user controls data context property.
The second workaround can be done like this:
<sdk:Label Name="label1" Content="{Binding ElementName=root, Path=DecimalProperty}" />
...where the root usercontrol tag is defined like this (this idea is from the link above also):
<UserControl x:Class="SilverlightDecimal.MainPage" x:Name="root" .... >
and this is in your user control's code-behind:
public decimal DecimalProperty
{
get
{
...
}
set
{
...
}
}

Related

What is the format of the DataType property for a DataTemplate or HierarchicalDataTemplate in WPF?

I am trying to understand what the format is for the DataType parameter for a DataTemplate or a HierarchicalDataTemplate. There are lots of examples scattered throughout the internet that I can copy and get working, but I don't understand what my options are.
For example:
<DataTemplate DataType="{x:Type model:DepartmentSelectionViewModel}">
I would like to understand what x:Type means. And what model:DepartmentSelectionViewModel means.
Or:
<HierarchicalDataTemplate DataType="{x:Type r:NetworkViewModel}" ItemsSource="{Binding Children}">
Again, it has x:Type. But this time r:NetworkViewModel.
Other examples will have sys: or local:. What do all these settings mean? How can I discover what other settings exist? (Is settings even the right word to describe them?)
model and r refer to XAML namespace mappings.
These are ofter found in the root tag or the XAML file and define the CLR namespaces in which the types (classes) DepartmentSelectionViewModel and NetworkViewModel are defined respectively:
<Window ... xmlns:model="clr-namespace:Project1" ... />
namespace Project1
{
public class DepartmentSelectionViewModel { ... }
}
You can define as many namespace mappings as you want.
x:Type refers to a type for which the implicit DataTemplate will be applied, i.e. the DataTemplate with the DataType property set to {x:Type model:DepartmentSelectionViewModel} will be applied to all DepartmentSelectionViewModel objects in the Items collection of the TreeView when the view is rendered.

binding combobox items to dictionary of enums

still pretty new at WPF and binding especially, but I have an enum which I will be using as properties on objects elsewhere in my project, but one of the very first kickoff points of the program will be the user selecting a single item from a combobox, which I want to match to the available enum options. I originally thought to have a dictionary object with the enum option as the key, and the value as a string for use in the UI presentation, and this is what I have been working towards. I have been searching around and thought I had it, but the combobox is populating blank.
I have a couple of questions;
Firstly, since I'm still not quite sure what is what in relation to binding, is this issue related to this post Target Exception Bug which I found in a comment on another question? If so, does this mean I'm barking up the wrong tree for the time being? And is there another way for me to achieve my goal?
Secondly, if its not related, have I missed something in the below code? I currently get no error in the output window and the project compiles fine.
Here's the enum (which lives in a separate namespace that has been added to the project references);
namespace WGM_lbr
{
public class Available_Wgms
{
private static Dictionary<Wgms,string> _wgmColl;
public static Dictionary<Wgms,string> WgmsCollection
{
get
{
return _wgmColl;
}
}
static Available_Wgms()
{
_wgmColl = new Dictionary<Wgms, string>() {
{Wgms.First, "First Dictionary item"},
//other Dictionary Items go here
}
}
public enum Wgms
{
First,
//other Enum options go here
}
}
}
My Resource declaration in app.xaml
<Application x:Class="The_First.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WGM="clr-namespace:WGM_lbr;assembly=WGM_lbr"
StartupUri="MainWindow.xaml">
<Application.Resources>
<BooleanToVisibilityConverter x:Key="b2v"/>
<WGM:Available_Wgms x:Key="WgmList"/>
</Application.Resources>
And finally the combobox and binding xaml (in case its relevant, this lives in a nest of wpf controls, up to a grid which lives on page, which is being loaded to mainwindow.xaml via a frame control using the page as the source. Both the page and mainwindow have declared the WGM namespace - I cut these out as this post is already long enough);
<ComboBox Name="cmbWgmSelector" Margin="5,0" ItemsSource="{Binding Source={StaticResource WgmList}}"/>
Any help/advice that can be provided is greatly appreciated.
Update the binding as below:
<ComboBox Name="cmbWgmSelector" Margin="5,0" DisplayMemberPath="Value" ItemsSource="{Binding Path=WgmsCollection, Source={StaticResource WgmList}}"/>

Programmatically Accessing a Silverlight Static Resource

I'd like to programmatically access static resources much as I would in XAML:
<TextBlock Text="{Binding Source={StaticResource My.Text.Key}}" />
This works whether my static resource is defined on the TextBlock, some parent element (e.g. UserControl) or even the application. It seems that either the StaticResource binding expression knows how to walk up the element tree, or the element itself does. I'd like to do the same thing programmatically:
<UserControl x:Class="MyCustomControl" ...>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources.xaml"/> <!-- Sets 'My.Text.Key' to System.String 'Hello, World!' -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
</UserControl>
public partial class MyCustomControl
{
public MyCustomControl()
{
InitializeComponent();
string myCustomValue = this.Resources[MyCustomValue] as string; // myCustomValue becomes null!
}
}
Even in this simple test, my resource can't seem to be accessed programmatically. And this is the simplified version of what I was trying to really do: find a static resource via an element that I have a custom dynamic property attached to (e.g. uiElement.Resources[key]).
Despite your comment to the contrary I doubt the use of "." in your resource key is really the source of your problem. In this situation the "." has no special meaning and would not impact how the resource is accessed. (I've tried and failed to reproduce any problem with it).
There is though a very big difference between using the {StaticResource MyName} mark up extension and an attempt to find the resource programmatically.
The markup extension causes the XamlParser to look for the specified key the Resources property of the FrameworkElement to which the property being assigned belongs. If the key is not found it looks for it in the parent FrameworkElement and it keeps going until it reaches the root FrameworkElement. If it is still not found it has a look in the Application's Resources property.
On the other hand this code:-
string myCustomValue = this.Resources[MyCustomValue] as string;
sf just looking in the single Resources property for the user control. No attempt is made to hunt down the key in ancestors or in the application resources. Its a simple Dictionary lookup. This I suspect is what was really tripping you up.
Having said that I would say the using "." in a resource key may not be a good idea. The "." does have meaning in various XAML scenarios already so using it in key names as well has the potential to confuse a developer reading the code even though Silverlight is quite happy with it.

wpf custom control not recognized

This is my first foray into custom controls, and it's not going well. I have a custom graph control derived from Canvas.
namespace Grapher2 {
public class SeriesManager : Canvas {
public SeriesManager() {
...
}
}
}
It's defined in the same project and namespace as my app. I tried adding a reference to the control in XAML as follows:
<Window x:Class="Grapher2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:graph="clr-namespace:Grapher2"
Title="Grapher" Width="800" Height="600">
<StackPanel Name="container" Width="700" Height="500">
<graph:SeriesManager Name="seriesManager" Width="700" Height="500" />
</StackPanel>
But when I try to reference the control name "seriesManager" in the code-behind for the Window, I get "The name 'seriesManager' does not exist in the current context."
Furthermore, the XAML editor will not render the Window, giving a huge stack trace with the error: "Type 'MS.Internal.Permissions.UserInitiatedNavigationPermission' in Assembly 'PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not marked as serializable."
I imagine the solution is something stupidly simple for anyone who's done custom controls. But I'm stumped.
did you try x:Name="seriesManager" in your xaml?
Edit: This may not be the issue seeing how you said your xaml isn't rendering. I'm guessing once you get the xaml to render in the designer... the code behind will work better.
Edit 2: Whenever I've had a problem with the designer rendering, it's because I'm doing something in the constructor of my custom control. Check your SeriesManager to see if you are doing something in its constructor that is causing a problem. Maybe you are referencing something that doesn't exist yet. If you do have extra code in your constructor, consider moving it to the UserControl_Loaded event.
Backing up Scott's answer here, since he helped me solve it:
What I did wrong was trying to access the control BEFORE InitializeComponent(), but was confused by 2 other error messages somewhere else in the code.
Just in case someone else has this error.

WPF Databinding to Custom Collection Objects

Public Sub New(ByVal log As Entities.LogSystem)
InitializeComponent()
Me.DataContext = log
End Sub
This is the the initializer for my custom control It passes in a single entity that has several property fields. This control is added to a parent control so that it appears in a stackpanel.
Anyway I am trying to get the specific data from this control into several different text boxes:
<UserControl x:Class="LogSystemPickerItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WavelengthIS.WISRED.UserControls"
Width="579" Height="122">
<UserControl.Resources>
<local:LogSystemPickerItem x:Key="Log"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource Log}}">
<Label Height="30" Name="Label1" VerticalAlignment="Top" Content="{Binding deptDescription}"/>
</Grid>
</UserControl>
As you can see i havent really gotten too far. I have tried many different ways to do this including using dependency properties...I just really cant find a tutorial that shows this specific circumstance...can anyone point me in the right direction?
If you're setting the DataContext in the code behind as per your first code snippet, there's no need to also do it in the XAML, so you can remove the "Log" resource and the corresponding DataContext assignment on the Grid.
Once you've done that, it should work assuming there is a deptDescription property on your log class.
... and in XAML you may do it this way...
<UserControl.DataContext>
<local:LogSystemPickerItem/>
</UserControl.DataContext>

Resources