Search code examples
windows-phone-7data-bindingdictionarydatatemplate

Binding Data to Panorama.TitleTemplate


I have been trying to customize the title area of my panorama page by using Panorama.TitleTemplate property and a dictionary for binding data to it without any success. My XAML code is as follow:

<Grid x:Name="LayoutRoot">
    <controls:Panorama Name="siteHubPanoramaControl">
        <controls:Panorama.TitleTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Height="75" Margin="0,75,0,0" Width="470" DataContext="{Binding}">
                    <Image Source="{Binding imageSource}" />
                    <TextBlock Text="{Binding name}" />
                </StackPanel>
            </DataTemplate>
        </controls:Panorama.TitleTemplate>

        <!--Panorama item one-->
        <controls:PanoramaItem Header="Site Info">
            <Grid/>
        </controls:PanoramaItem>

        <!--Panorama item two-->
        <controls:PanoramaItem Header="Others">
            <Grid/>
        </controls:PanoramaItem>
    </controls:Panorama>
</Grid>

I bind the dictionary to the data template by using the following code:

Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("name", this.name);
dictionary.Add("imageSource", "http://...");

siteHubPanoramaControl.DataContext = dictionary;

I have been searching for a solution but couldn't find one. I will be glad if you can help me on this problem.

Also is there a good source to learn about data binding?

Thanks in advance...


Solution

  • Both name and imageSource are not property. It is just key in your dictionary. So, when you are trying to bind those two, it couldn't find any property with those name.

    You have to expose those values into a property. For example,

    public string Name
    {
        get { return dictionary["name"]; }
    }
    

    I am not sure of any other way, but that would be my idea. It should work I think.

    Edit:

    Ok, assuming you are using MVVM pattern, this below code should work.

    ViewModel

        public class MainPageViewModel
        {
            private Dictionary<string,string> _dictionary = new Dictionary<string, string>();
    
            public MainPageViewModel()
            {
                _dictionary.Add("name", "Foo");
                _dictionary.Add("imageSource", "http://");
            }
    
            public string Name
            {
                get { return _dictionary["name"]; }
            }
    
            public string ImageSource
            {
                get { return _dictionary["imageSource"]; }
            }
        }
    

    Code-behind

    public partial class MainPage : PhoneApplicationPage
    {
        private MainPageViewModel _vm;
        // Constructor
        public MainPage()
        {
            InitializeComponent();
    
            _vm = new MainPageViewModel();
            DataContext = _vm;
        }
    }
    

    XAML

    <Grid x:Name="LayoutRoot">
        <phone:Panorama Name="siteHubPanoramaControl">
            <phone:Panorama.Title>
                <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding ImageSource}"/>
                        <TextBlock Text="{Binding Name}" />
                    </StackPanel>
            </phone:Panorama.Title>
            <!--Panorama item one-->
            <phone:PanoramaItem Header="Foo">
                <Grid/>
            </phone:PanoramaItem>
    
            <!--Panorama item two-->
            <phone:PanoramaItem Header="Others">
                <Grid/>
            </phone:PanoramaItem>
        </phone:Panorama>
    </Grid>
    

    For the XAML, instead of using Panorama.TitleTemplate and applying DataTemplate, use Panorama.Title instead which make it more easier. I tried with TitleTemplate, I can only make it works to bind the title but not the image. So the easiest workaround is to use Panorama.Title.