Привязка к XMLDataProvider - PullRequest
       16

Привязка к XMLDataProvider

0 голосов
/ 04 января 2012

Сделан простой тестовый проект, в котором я пытаюсь привязаться к источнику xmldatasource в прототипной модели представления

public partial class Window1 : Window
{
    //private XmlDataProvider _provider = new XmlDataProvider(); 
    private MyViewModel _myViewModel = new MyViewModel();
    public Window1()
    {
        InitializeComponent();
        this.DataContext = _myViewModel ;
    }    
}

public class MyViewModel
{    
    public MyViewModel()
    {
        LoadXMLData();
    }

    private XmlDataProvider _provider = new XmlDataProvider(); 
    public XmlDataProvider Reports
    {
        get { return _provider; }
        set { _provider = value; }
    }    

    private void LoadXMLData()
    {
        string filePath = Directory.GetCurrentDirectory() + @"\Reports2.xml";

        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        doc.Load(filePath);
        _provider.Document = doc;
        _provider.XPath = @"Reports/Report";
    }
}

Если я попытаюсь привязать список, как это. Я ничего не получаю

<ListBox x:Name="TeamsListBox" Margin="0,0,0,20" DockPanel.Dock="Left"
    ItemsSource="{Binding Reports}"
    ItemTemplate="{StaticResource teamItemTemplate}"
    IsSynchronizedWithCurrentItem="True"
    Visibility="Visible" SelectionMode="Single">
</ListBox>

Если я вместо этого изменю текст данных на

this.DataContext = _myViewModel.Reports

И список на

<ListBox x:Name="TeamsListBox" Margin="0,0,0,20" DockPanel.Dock="Left"
    ItemsSource="{Binding}"
    ItemTemplate="{StaticResource teamItemTemplate}"
    IsSynchronizedWithCurrentItem="True"
    Visibility="Visible" SelectionMode="Single">
</ListBox>

Тогда это работает, как мне привязаться к модели представления, чтобы я мог заполнить ее больше, чем просто в xmldatasource

Если я поставлю точку останова в свойстве Report, я смогу увидеть, что она вызывается, когда я выполняю {Binding Reports}, но список все еще пуст.

UPDATE

Я могу сделать эту привязку в коде, и тогда она будет работать

 Binding binding = new Binding();
            binding.Source = _myViewModel.Reports;
            binding.XPath = @"Reports/Report";
            TeamsListBox.SetBinding(ListBox.ItemsSourceProperty, binding);

Почему я не могу сделать это в XAML

1 Ответ

0 голосов
/ 05 января 2012

Похоже, у меня были некоторые проблемы с пониманием XPath, и мой общий вопрос был о том, как связать динамический xmldataprovider в модели представления с xaml. Решил вот так.

XML

<?xml version="1.0" encoding="utf-8"?>
<Reports xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Report Id="AAAAA-ABBB">
    <DocId>30110001</DocId>
    <DocName>Report name1</DocName>
    <DocType>2010-01-01</DocType>
    <Status>1</Status>
    <CreatedById>1</CreatedById>
    <SiteId>1</SiteId>
    <Language>1</Language>
    <Updated>2011-01-01</Updated>
    <Published>2011-01-01</Published>
    <FilePath>c:\\reports\20011001.docx</FilePath>
  </Report>
  <Report Id="AAAAA-ABBC">
    <DocId>30110002</DocId>
    <DocName>Report name2</DocName>
    <DocType>2010-01-01</DocType>
    <Status>1</Status>
    <CreatedById>1</CreatedById>
    <SiteId>1</SiteId>
    <Language>1</Language>
    <Updated>2011-01-01</Updated>
    <Published>2011-01-01</Published>
    <FilePath>c:\\reports\20011001.docx</FilePath>
  </Report>
</Reports>

Window1

    <Window x:Class="WpfApplication2.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
              Title="Window1" Height="300" Width="300">
        <Window.Resources>

            <DataTemplate x:Key="reportItemTemplate">
                <StackPanel Orientation="Horizontal">
                <Label Content="{Binding XPath=DocId}"/>
                    <Label Content="{Binding XPath=DocName}"/>
                </StackPanel>
            </DataTemplate>
        </Window.Resources>
        <StackPanel  DataContext="{Binding LocalReports}" >
            <ListBox  

            ItemsSource="{Binding}"
                ItemTemplate="{StaticResource reportItemTemplate}"
                         IsSynchronizedWithCurrentItem="True"
                         Visibility="Visible" SelectionMode="Single"
                />
            <TextBox Text="{Binding XPath=DocId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <TextBox Text="{Binding XPath=DocName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <Button Content="Button" Height="23" Name="button1" Click="button1_Click" />
        </StackPanel>

    </Window> 

Window1.xaml.cs

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        //private XmlDataProvider _provider = new XmlDataProvider(); 
        private MyViewModel _myViewModel = new MyViewModel();

        public Window1()
        {
            InitializeComponent();

            this.DataContext = _myViewModel;


        }


         private void button1_Click(object sender, RoutedEventArgs e)
         {
             _myViewModel.Save();
         }

    }

    public class MyViewModel
    {

        public MyViewModel()
        {
                      }

        private XmlDataProvider _provider;
        public XmlDataProvider LocalReports
        {

            get
            {
                String file = Directory.GetCurrentDirectory() + @"\Reports2.xml";
                _provider = new XmlDataProvider()
                {
                    Source = new Uri(file, UriKind.Absolute),
                    XPath = "Reports/Report"
                };
                return _provider;
            }
        }



        }


        public  void Save()
        {
            string source = _provider.Source.LocalPath;
            _provider.Document.Save(source);
        }
    }
}
...