0

I have a user control that sets programmatically a listbox's data source (an XmlDataProvider and a DataTemplate to be exact) but during runtime it never properly shows up. When the user control is loaded. All the setup for the dataproviders are not reflecting.

Can you help me with this one? I'm really new in developing WPF applications.

TIA

Here's the code:

XAML

<UserControl x:Class="ENGAGIAUCL.Views.ImageViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="500" Width="550">
    <UserControl.Resources>
        <XmlDataProvider x:Key="FormDataProvider"/>
        <DataTemplate x:Key="FormTemplate">
            <Border Background="#2200FF00"
                    BorderBrush="Black" 
                    BorderThickness="1"
                    CornerRadius="8"  
                    Margin="2,4,2,4" 
                    Padding="4">
                <StackPanel HorizontalAlignment="Stretch">
                    <TextBlock Text="{Binding XPath=name}" />
                </StackPanel>
            </Border>
        </DataTemplate>
    </UserControl.Resources>
    <DockPanel>
        <Border DockPanel.Dock="Top"
                Height="45">
            <TextBlock x:Name="tbkContentTitle"
                       Text="Content Title Goes Here" 
                       VerticalAlignment="Center" 
                       HorizontalAlignment="Center"
                       FontSize="20">
            </TextBlock>
        </Border>
        <DockPanel>
            <Border DockPanel.Dock="Bottom">
            </Border>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="150"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <ListBox x:Name="lbPreview" 
                     IsSynchronizedWithCurrentItem="True"
                     VerticalAlignment="Top" 
                     Height="455" 
                     Grid.Column="0"
                     ItemsSource="{Binding}">
                </ListBox>
                <Frame x:Name="ActualContentFrame" 
                                           Grid.Column="1"
                       Source="{Binding XPath=url}">
                </Frame>
            </Grid>
        </DockPanel>
    </DockPanel>
</UserControl>

And here is the .cs file

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;

using EngagiaCL.CommonObjects;
using EngagiaCL.Functions;

namespace ENGAGIAUCL.Views
{
    /// <summary>
    /// Interaction logic for ImageViewer.xaml
    /// </summary>
    public partial class ImageViewer : UserControl
    {
        public ImageViewer()
        {
            InitializeComponent();
            Loaded += (s, e) =>
                {
                    LoadContents();
                };
        }

        #region Methods
        private void LoadContents()
        {
            if (CurrentUser != null)
            {
                XmlDataProvider provider = (XmlDataProvider)this.FindResource("FormDataProvider");
                DataTemplate template = (DataTemplate)this.FindResource("FormTemplate");
                Binding templatebinding = new Binding();

                provider.Document = CurrentUser.UserDoc;
                provider.XPath = GetResourcePath();

                template.DataType = (object)GetDataTemplateObject();
                Resources["FormDataProvider"] = provider;
                Resources["FormTemplate"] = template;
            }
        }
        private string GetResourcePath()
        {
            string path = string.Empty;

            if (ContentType == "ADMIN")
            {
                path = "/SyncLoginResponse/AdminForms/AdminForm";
            }
            else
            {
                path = "/SyncLoginResponse/Forms/Form";
            }

            return path;
        }
        private string GetDataTemplateObject()
        {
            string templateobject = string.Empty;

            if (ContentType == "ADMIN")
            {
                templateobject = "AdminForm";
            }
            else
            {
                templateobject = "Form";
            }

            return templateobject;
        }
        #endregion

        #region Properties
        public UserInformation CurrentUser { get; set; }
        public string ContentType { get; set; }
        #endregion
    }
}

And here's the xml for reference:

</SyncLoginResponse>
    <AdminForms>
        <AdminForm>
            <name>Best Form Ever/html</name>
            <url>
                http://blahblahblah/
            </url>
        </AdminForm>
    </AdminForms>
</SyncLoginResponse>

Things to note:

  1. CurrentUser is an object which contains the xml document within the UserDoc property.
  2. Most of what I did in this application are bits and pieces of what I understood in googling so kindly bear with me.

1 Answers1

0

Honestly I am unable to understand if yours is a new coding practise for loading a WPF UI, but few things look like a miss...

  1. Your ListBox.ItemsSource is bound as {Binding} i.e. bound to the DataContext of the entire View, but nowhere in your code behind, have you set the DataContext of the View or any higher level parent os the ListBox.

  2. Your templateBinding variable from code behind is not used anywhere after creation.

  3. Why are you setting FormDataProvider and FormTemplate again at the end of your LoadContents method? If you are wanting to "Refresh" your Resources dictionary then that is not the correct way.

For refreshing your Resources you need to remove and add resources in your Resources dictionary and at the same time use DynamicResource markup reference.

Let me know what is it that you exactly want to achieve.

WPF-it
  • 19,625
  • 8
  • 55
  • 71
  • Thanks for replying, sorry if my coding is rather messy. I initially coded the resource value for FormDataProvider this way: ((XmlDataProvider)Resources["FormDataProvider"]).Document = CurrentUser.UserDoc; But this didn't work. What I hope to happen is: 1. Once, the user control is Loaded, depending on the xml stream feed that I feed it, I would be able to programmatically define its XmlDocument and its XPath.(eg.: If the xml is from an Admin, the XPath would lead to the available AdminForms node) 2. Bind the result to the listbox and display a selected list item into a frame. Thanks – chriscorn Sep 12 '11 at 10:21