开发者

Programmatic binding of listbox not working in WPF

开发者 https://www.devze.com 2023-04-04 16:41 出处:网络
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 l

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.Window开发者_开发问答s.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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号