none
Key cannot be null?

    Question

  • I have some attached properties and a radio button style. I am getting the key cannot be null error. When I click on the error it takes me to the Content property of the "labelAbbreviation" element and I am not sure why.

    Here is the style:

    <Style x:Key="PageRadioButton" TargetType="{x:Type RadioButton}">
        <Setter Property="Margin" Value="3,0"/>
        <Setter Property="Width" Value="70"/>
        <Setter Property="Height" Value="68"/>
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type RadioButton}">
              <Grid x:Name="gridButtonWrapper">
                <Grid.RowDefinitions>
                  <RowDefinition Height="50"/>
                  <RowDefinition Height="17"/>
                </Grid.RowDefinitions>
                <Border x:Name="border" Grid.Row="0" Grid.Column="0" Width="65" Height="40" Background="{TemplateBinding Background}" BorderBrush="White" BorderThickness="2" CornerRadius="2.5">
                  <Label x:Name="labelAbbreviation" Content="{TemplateBinding Aps:AttachedProperties.Abbreviation}" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Century Gothic" FontSize="25" FontWeight="Bold" Foreground="White" Margin="-2,-3,0,0"/>
                </Border>
                <Label x:Name="labelFullName" Grid.Row="1" Grid.Column="0" Content="{TemplateBinding Aps:AttachedProperties.FullName}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="12" Margin="-10,-11,-10,0"/>
              </Grid>
              <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                  <Setter Property="LayoutTransform" TargetName="border">
                    <Setter.Value>
                      <ScaleTransform ScaleX="1.15" ScaleY="1.25"/>
                    </Setter.Value>
                  </Setter>
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                  <Setter Property="Margin" TargetName="border" Value="-6,-7,-6,0"/>
                </Trigger>
                <Trigger Property="IsChecked" Value="True">
                  <Setter Property="LayoutTransform" TargetName="border">
                    <Setter.Value>
                      <ScaleTransform ScaleX="1.15" ScaleY="1.25"/>
                    </Setter.Value>
                  </Setter>
                </Trigger>
                <Trigger Property="IsChecked" Value="True">
                  <Setter Property="Margin" TargetName="border" Value="-6,-7,-6,0"/>
                </Trigger>
              </ControlTemplate.Triggers>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    

    Here is the button dropped on the page:

    <RadioButton x:Name="radioButtonButtons" Style="{DynamicResource PageRadioButton}" Background="#FF797777" Aps:AttachedProperties.Abbreviation="BTN" Aps:AttachedProperties.FullName="Buttons"/>
    

    And here are the attached properties.

    public static readonly DependencyProperty AbbreviationProperty;
    
    public static string GetAbbreviation(DependencyObject obj)
    {
      return (string)obj.GetValue(AbbreviationProperty);
    }
    
    public static void SetAbbreviation(DependencyObject obj, string value)
    {
      obj.SetValue(AbbreviationProperty, value);
    }
    
    public static readonly DependencyProperty FullNameProperty;
    
    public static string GetFullName(DependencyObject obj)
    {
      return (string)obj.GetValue(FullNameProperty);
    }
    
    public static void SetFullName(DependencyObject obj, string value)
    {
      obj.SetValue(FullNameProperty, value);
    }

    Which are registered as attached in the constructor like so:

    AbbreviationProperty = DependencyProperty.RegisterAttached("Abbreviation",
            typeof(string), typeof(AttachedProperties), new FrameworkPropertyMetadata("BTN"));
    
    FullNameProperty = DependencyProperty.RegisterAttached("FullName",
            typeof(string), typeof(AttachedProperties), new FrameworkPropertyMetadata("Button"));
    
    I have done this exact same thing before, so I am wondering if I just can't TemplateBind to the Content of a Label? Thanks in advance.

     

    Wednesday, August 11, 2010 4:59 PM

Answers

  • Hi BBauer42,

    I can’t seem to be able to reproduce this, I copied your code 1:1 didn’t change a line and everything works fine. The only time I got “Key cannot be null” error was when at compile time when I forgot to initialize/register the attached properties in the static constructor. I’m using VS 2008 (9.0.30729.1 SP) and .NET Framework 3.5 SP1.

    What VS/.NET version are you using?
     - Levi

    PS: Just for reference, here is my code:

    <Window

        x:Class="AttachedProps.Window1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:Aps="clr-namespace:AttachedProps"

        Title="Window1" Height="300" Width="300" Background="Gray">

        <Window.Resources>

            <Style x:Key="PageRadioButton" TargetType="{x:Type RadioButton}">

                <Setter Property="Margin" Value="3,0"/>

                <Setter Property="Width" Value="70"/>

                <Setter Property="Height" Value="68"/>

                <Setter Property="Template">

                    <Setter.Value>

                        <ControlTemplate TargetType="{x:Type RadioButton}">

                            <Grid x:Name="gridButtonWrapper">

                                <Grid.RowDefinitions>

                                    <RowDefinition Height="50"/>

                                    <RowDefinition Height="17"/>

                                </Grid.RowDefinitions>

                                <Border

                                    x:Name="border" Grid.Row="0" Grid.Column="0"

                                    Width="65" Height="40"

                                    Background="{TemplateBinding Background}"

                                    BorderBrush="White"

                                    BorderThickness="2"

                                    CornerRadius="2.5">

                                    <Label

                                        x:Name="labelAbbreviation"

                                        Content="{TemplateBinding Aps:AttachedProperties.Abbreviation}"

                                        VerticalAlignment="Center" HorizontalAlignment="Center"

                                        FontFamily="Century Gothic" FontSize="25" FontWeight="Bold"

                                        Foreground="White" Margin="-2,-3,0,0"/>

                                </Border>

                                <Label

                                    x:Name="labelFullName" Grid.Row="1" Grid.Column="0"

                                    Content="{TemplateBinding Aps:AttachedProperties.FullName}"

                                    HorizontalAlignment="Center" VerticalAlignment="Center"

                                    Foreground="White" FontSize="12" Margin="-10,-11,-10,0"/>

                            </Grid>

                            <ControlTemplate.Triggers>

                                <Trigger Property="IsMouseOver" Value="True">

                                    <Setter Property="LayoutTransform" TargetName="border">

                                        <Setter.Value>

                                            <ScaleTransform ScaleX="1.15" ScaleY="1.25"/>

                                        </Setter.Value>

                                    </Setter>

                                </Trigger>

                                <Trigger Property="IsMouseOver" Value="True">

                                    <Setter Property="Margin" TargetName="border" Value="-6,-7,-6,0"/>

                                </Trigger>

                                <Trigger Property="IsChecked" Value="True">

                                    <Setter Property="LayoutTransform" TargetName="border">

                                        <Setter.Value>

                                            <ScaleTransform ScaleX="1.15" ScaleY="1.25"/>

                                        </Setter.Value>

                                    </Setter>

                                </Trigger>

                                <Trigger Property="IsChecked" Value="True">

                                    <Setter Property="Margin" TargetName="border" Value="-6,-7,-6,0"/>

                                </Trigger>

                            </ControlTemplate.Triggers>

                        </ControlTemplate>

                    </Setter.Value>

                </Setter>

            </Style>

        </Window.Resources>

        <StackPanel VerticalAlignment="Center">

            <RadioButton Style="{StaticResource PageRadioButton}">Foo</RadioButton>

            <RadioButton Style="{StaticResource PageRadioButton}">Foo</RadioButton>

        </StackPanel>

    </Window>

     

    using System.Windows;

     

    namespace AttachedProps

    {

        public static class AttachedProperties

        {

            public static readonly DependencyProperty AbbreviationProperty;

     

            static AttachedProperties()

            {

                AbbreviationProperty = DependencyProperty.RegisterAttached("Abbreviation",

                        typeof(string), typeof(AttachedProperties),

                        new FrameworkPropertyMetadata("BTN"));

     

                FullNameProperty = DependencyProperty.RegisterAttached("FullName",

                        typeof(string), typeof(AttachedProperties),

                        new FrameworkPropertyMetadata("Button"));

            }

     

            public static string GetAbbreviation(DependencyObject obj)

            {

                return (string)obj.GetValue(AbbreviationProperty);

            }

     

            public static void SetAbbreviation(DependencyObject obj, string value)

            {

                obj.SetValue(AbbreviationProperty, value);

            }

     

            public static readonly DependencyProperty FullNameProperty;

     

            public static string GetFullName(DependencyObject obj)

            {

                return (string)obj.GetValue(FullNameProperty);

            }

     

            public static void SetFullName(DependencyObject obj, string value)

            {

                obj.SetValue(FullNameProperty, value);

            }

        }

    }

    Tuesday, August 17, 2010 6:03 PM

All replies

  • Does your xaml contain a definition of Aps? Something like
    xmlns:Aps="clr-namespace:Aps"
    Wednesday, August 11, 2010 5:05 PM
  • Yes, here it is:

    xmlns:Aps="clr-namespace:My.Infrastructure;assembly=My.Infrastructure"

    Wednesday, August 11, 2010 5:14 PM
  • This may not be relevant, but I believe that you need to wrap attached properties in parentheses:

    {TemplateBinding (Aps:AttachedProperties.Abbreviation)}

    Wednesday, August 11, 2010 6:24 PM
  • It would be helpful if I could see the whole error message with its stack trace. Can you post it here? Thx -Levi

    Wednesday, August 11, 2010 8:56 PM
  • Hi,

    TemplateBinding is only applicable for dependency properties which you cannot assign attached properties.  From your XAML, you just change the TemplateBinding as Binding like given below. It should work fine.

    <Label x:Name="labelAbbreviation" Content="{Binding Aps:AttachedProperties.Abbreviation}" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Century Gothic" FontSize="25" FontWeight="Bold" Foreground="White" Margin="-2,-3,0,0"/>

     

    <Label x:Name="labelFullName" Grid.Row="1" Grid.Column="0" Content="{Binding Aps:AttachedProperties.FullName}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="12" Margin="-10,-11,-10,0"/>

     

     

    Hope it should resolve your issue.


    Prabu (http://prabu-guru.blogspot.com/)
    Wednesday, August 11, 2010 9:02 PM
  • I don't think that is the case, just look at the declaration of my Attached Property.... it is a DependencyProperty. I have also successfully done this before with a CornerRadiusRB property for a radio button with a border inside of it. The syntax in my sample is essentially identical to the working sample.

     

    public static readonly DependencyProperty AbbreviationProperty;
    Thursday, August 12, 2010 3:09 AM
  • Hi BBauer42,

    when u r binding to Attached properties u need to use Parenthesis

    arounf it...

    For example here Image.Width is the Attached Property so i need to use Parenthesis

     <Storyboard x:Key="FigStoryEnter">
        <DoubleAnimation 
       From="300" To="600" 
       Duration="00:00:01" 
       Storyboard.TargetProperty="(Image.Width)"
       FillBehavior="HoldEnd"></DoubleAnimation>
      </Storyboard>
    

    for more information check this link

    http://msdn.microsoft.com/en-us/library/ms752300.aspx#Path_Syntax

    i hope this woll help you.

    THanks,

    BHavik

    Mark it as answer if it realy helps you

    Thursday, August 12, 2010 4:34 AM
  • That didn't work. I get "Key cannot be null" with or without the parenthesis. Again, I have multiple working examples with attached properties, styles, and template binding that all work (without the parenthesis fyi). For some reason this configuration doesn't work. Here are some working examples copied directly from my project.

    CornerRadius="{TemplateBinding Aps:AttachedProperties.CornerRadiusRb}"
    Margin="{TemplateBinding Aps:AttachedProperties.ButtonBackgroundMargin}"
    Source="{TemplateBinding Aps:AttachedProperties.Image}"
    Source="{TemplateBinding Aps:AttachedProperties.ImageMouseOver}"

    The only difference here is that I am trying to TemplateBind to the Content property of a Label. What is different about the Content property? This is where the cursor is placed when I get the Key cannot be null error.

    Content="{TemplateBinding Aps:AttachedProperties.Abbreviation}"

    The syntax is identical.

     

    Thursday, August 12, 2010 1:34 PM
  • FYI, I changed the Label to a TextBlock and it worked great. This confirms my belief that the Content property of a label is handled differently than other control properties (like Text, CornerRadius, Margin, and Source). I am still curious as to what the problem is but this workaround will do for now. Thanks.

     

    <Border x:Name="border" Grid.Row="0" Grid.Column="0" Width="65" Height="40" Background="{TemplateBinding Background}" BorderBrush="White" BorderThickness="2" CornerRadius="2.5">
      <TextBlock x:Name="labelAbbreviation" Text="{TemplateBinding Aps:AttachedProperties.Abbreviation}" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Century Gothic" FontSize="25" FontWeight="Bold" Foreground="White" Margin="-2,-3,0,0"/>
    </Border>
    
    

    Thursday, August 12, 2010 3:36 PM
  • Hi BBauer42,

    Sorry for my later reply. Yes, I have reproduced this issue, still now I do not get any result. I will consult this issue internal. If I get any feedback, I will update here. It seems now the workaround is to use the TextBlock instead of the Label.

    Sincerely,

    Bob Bao

    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Friday, August 13, 2010 9:46 AM
    Moderator
  • Hi BBauer42,

    I can’t seem to be able to reproduce this, I copied your code 1:1 didn’t change a line and everything works fine. The only time I got “Key cannot be null” error was when at compile time when I forgot to initialize/register the attached properties in the static constructor. I’m using VS 2008 (9.0.30729.1 SP) and .NET Framework 3.5 SP1.

    What VS/.NET version are you using?
     - Levi

    PS: Just for reference, here is my code:

    <Window

        x:Class="AttachedProps.Window1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:Aps="clr-namespace:AttachedProps"

        Title="Window1" Height="300" Width="300" Background="Gray">

        <Window.Resources>

            <Style x:Key="PageRadioButton" TargetType="{x:Type RadioButton}">

                <Setter Property="Margin" Value="3,0"/>

                <Setter Property="Width" Value="70"/>

                <Setter Property="Height" Value="68"/>

                <Setter Property="Template">

                    <Setter.Value>

                        <ControlTemplate TargetType="{x:Type RadioButton}">

                            <Grid x:Name="gridButtonWrapper">

                                <Grid.RowDefinitions>

                                    <RowDefinition Height="50"/>

                                    <RowDefinition Height="17"/>

                                </Grid.RowDefinitions>

                                <Border

                                    x:Name="border" Grid.Row="0" Grid.Column="0"

                                    Width="65" Height="40"

                                    Background="{TemplateBinding Background}"

                                    BorderBrush="White"

                                    BorderThickness="2"

                                    CornerRadius="2.5">

                                    <Label

                                        x:Name="labelAbbreviation"

                                        Content="{TemplateBinding Aps:AttachedProperties.Abbreviation}"

                                        VerticalAlignment="Center" HorizontalAlignment="Center"

                                        FontFamily="Century Gothic" FontSize="25" FontWeight="Bold"

                                        Foreground="White" Margin="-2,-3,0,0"/>

                                </Border>

                                <Label

                                    x:Name="labelFullName" Grid.Row="1" Grid.Column="0"

                                    Content="{TemplateBinding Aps:AttachedProperties.FullName}"

                                    HorizontalAlignment="Center" VerticalAlignment="Center"

                                    Foreground="White" FontSize="12" Margin="-10,-11,-10,0"/>

                            </Grid>

                            <ControlTemplate.Triggers>

                                <Trigger Property="IsMouseOver" Value="True">

                                    <Setter Property="LayoutTransform" TargetName="border">

                                        <Setter.Value>

                                            <ScaleTransform ScaleX="1.15" ScaleY="1.25"/>

                                        </Setter.Value>

                                    </Setter>

                                </Trigger>

                                <Trigger Property="IsMouseOver" Value="True">

                                    <Setter Property="Margin" TargetName="border" Value="-6,-7,-6,0"/>

                                </Trigger>

                                <Trigger Property="IsChecked" Value="True">

                                    <Setter Property="LayoutTransform" TargetName="border">

                                        <Setter.Value>

                                            <ScaleTransform ScaleX="1.15" ScaleY="1.25"/>

                                        </Setter.Value>

                                    </Setter>

                                </Trigger>

                                <Trigger Property="IsChecked" Value="True">

                                    <Setter Property="Margin" TargetName="border" Value="-6,-7,-6,0"/>

                                </Trigger>

                            </ControlTemplate.Triggers>

                        </ControlTemplate>

                    </Setter.Value>

                </Setter>

            </Style>

        </Window.Resources>

        <StackPanel VerticalAlignment="Center">

            <RadioButton Style="{StaticResource PageRadioButton}">Foo</RadioButton>

            <RadioButton Style="{StaticResource PageRadioButton}">Foo</RadioButton>

        </StackPanel>

    </Window>

     

    using System.Windows;

     

    namespace AttachedProps

    {

        public static class AttachedProperties

        {

            public static readonly DependencyProperty AbbreviationProperty;

     

            static AttachedProperties()

            {

                AbbreviationProperty = DependencyProperty.RegisterAttached("Abbreviation",

                        typeof(string), typeof(AttachedProperties),

                        new FrameworkPropertyMetadata("BTN"));

     

                FullNameProperty = DependencyProperty.RegisterAttached("FullName",

                        typeof(string), typeof(AttachedProperties),

                        new FrameworkPropertyMetadata("Button"));

            }

     

            public static string GetAbbreviation(DependencyObject obj)

            {

                return (string)obj.GetValue(AbbreviationProperty);

            }

     

            public static void SetAbbreviation(DependencyObject obj, string value)

            {

                obj.SetValue(AbbreviationProperty, value);

            }

     

            public static readonly DependencyProperty FullNameProperty;

     

            public static string GetFullName(DependencyObject obj)

            {

                return (string)obj.GetValue(FullNameProperty);

            }

     

            public static void SetFullName(DependencyObject obj, string value)

            {

                obj.SetValue(FullNameProperty, value);

            }

        }

    }

    Tuesday, August 17, 2010 6:03 PM
  • I am using .NET 3.5 and VS2010
    Thursday, August 19, 2010 2:17 PM
  • Just tested on VS2010 still works fine.

    In your case do you see that error during compilation or at run-time? Can you try the exact code I posted and see if you still get the same error?

    Thanks,
     -Levi

    Thursday, August 19, 2010 8:04 PM
  • Strange, I tested Levi's code, it is fine.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Friday, August 20, 2010 7:47 AM
    Moderator
  • Bob,

    You said you were able to reproduce the error before. How is your code different from mine?

    - Levi
    Friday, August 20, 2010 8:06 AM
  • Hi,

    Below is my old test case, they look same: http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/TestCase/20100820%5E_KeyIsNull%5E_TestCase.zip

    I tested it again just now, it woeks fine. The key is null error just happened when we specify the TemplatBinding as {TemplateBinding (l:AttachedProperties.StringAttached)}.

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Friday, August 20, 2010 8:24 AM
    Moderator
  • Yes, it seems to be intermittent to me as well.
    Friday, August 20, 2010 2:21 PM