C# Bindings with WPF and XML files

Hi!

I have some problems with getting my bindings in WPF to work.

I have two problems.
a) I want to bind the contents of a ListBox to a static XML file. The XML file looks as follows:
<start>
  <car>
  <carName>Name 1</carName>
  </car>
  <truck>
  <truckName>Name 2</truckName>
  </truck>
</start>

Open in new window

I want Name1 and Name2 to be displayed as two items. And for this I thought I should use datatemplates, and that the DataType whould mapped to the different xml tags
<Grid>
        <Grid.Resources>
            <XmlDataProvider Source="test.xml" XPath="start" x:Key="xml"></XmlDataProvider>
           <DataTemplate DataType="car">
                <TextBlock Text="{Binding Path=carName}"></TextBlock>
            </DataTemplate>
           <DataTemplate DataType="truck">
                <TextBlock Text="{Binding Path=truckName}"></TextBlock>
            </DataTemplate>
        </Grid.Resources>

        <ListBox Height="261" HorizontalAlignment="Left" Margin="24,23,0,0" Name="listBox1" VerticalAlignment="Top" Width="162" DataContext="{Binding Source={StaticResource xml}}">
        </ListBox>
    </Grid>

Open in new window


b) Secondly I would like to modify this XML file during the execution of my program. And if a new tag, <damaged> is added to a car or a truck then I would change the colour of this item. I have that code running fine if the xml contains the <damaged> tag at startup, but I miss some way of getting the Listbox to reevaluate. Is there a way to force it to update all elements in the list?

kind regards
Edarn


EdarnAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

David L. HansenProgrammer AnalystCommented:
This seems like an awkward way of doing things.  Perhaps if you give us a broader picture of what your aim is (a general statement of the purpose of the software and of your business) and what these changes should accomplish, we could give you some easier, more effective options.
0
EdarnAuthor Commented:
Hi sl8rz!

I´m writing a testtool for the company I work for. The tool is used to run automated tests. In that program I have a TreeView box that shows what tests to be run. It looks something like this:
-SessionName
---TestCase1
------TestStepA
------TestStepB
------TestStepC
---TestCase2
------TestStepB
------TestStepD
---TestCase3
------TestStepF

Open in new window


This list is bound to an xml file that contains all this information. That XML file looks something like:
<start>
  <sessionName>
    <ParameterA value="A"/>
    <ParameterB value="B"/>
    <testcases>
      <caseA>
        <ParameterA override="false"/>
        <ParameterB override="false"/>
        <steps>
          <stepA>
            <ParameterA override="false"/>
            <ParameterB override="false"/>
          </stepA>
          <stepB>
            <ParameterA override="false"/>
            <ParameterB override="false"/>
          </stepB>
        </steps>
      </caseA>
      <caseB>
        <ParameterA override="false"/>
        <ParameterB override="false"/>
        <steps>
          <stepA>
            <ParameterA override="YES" value="XYZ"/>  <=======NOTE THE CHANGED VALUE
            <ParameterB override="YES" value="ABC"/>  <=======AND THE OVERRIDE attribute.
          </stepA>
          <stepB>
            <ParameterA override="false"/>
            <ParameterB override="false"/>
          </stepB>
        </steps>
      </caseB>
    <caseC>
      ...
    </caseC>
    </testcases>
  </sessionName>
</start>

</xml

Open in new window


This means that if a user selects the Session the TreeView, then I will get the entire XML code for that session, testcases and all steps in the OnSelectionChanged.
If a user selects a Testcase, then I will get that testcase + its teststeps xmlcode. And if only selecting a teststep, then I will only get that steps xml code.

Now this is how it works: The parameters set on the SESSION level is propagated down and used in all Cases and Steps UNLESS if there is an override of the parameter in any case/step. If a case overrides a parameter then it is used by all the steps belonging to this testcase. If a single teststep parameters is overrided, then it is only used in this teststep.

Now when displaying this list containing aprox 50-100 testcases, and each of them containing 30-50 teststeps this list get very long. So by default the list only shows the Session level and the Testcase level. (All the steps are collapsed and a '+' sign is displayed - if clicking on the ´+´sign the steps are expanded for this TC.....that´s the way a TreeView works I guess ;-D).

As SOME, and only a FEW teststeps needs to have changed parameters it would be very good if I could change the background color of that testStep. And that is easily done if connecting the ListElements backgroundColor to a IValueConverter. This checks the stepXML code that it is bound to for the override attribue and if set it changes the background color.

So far the program works perfect. And as soon as the test STEP changes to/from override the background color changes. So WPF finds out about the change themselves.

Now the problem: When one of the steps that belongs to a testcase contains one or more parameters that is overridden.StepA in CaseB in the example. Then I would ALSO want the bg color of that case to changed. This can be done in the same way as for the item with a different IValueConverter that scans all the steps belonging to this TestCase and if any override is found the backgroundcolor is changed.
This works perfectly fine too, IF the xml file is changed before the program starts. But it is NOT updated if I modify the teststep at runtime. Then it is only the testStep that get´s changed.

So to solve my immediate problem I would just need a way to get the TreeView listbox to re-evaluate. But as I don´t really understand how the DataTemplates work when using it with XML files, I thought the original question I asked would help me understand it better.

I hope this helps understanding my problem. :-)

Kind Regards
Thomas
0
David L. HansenProgrammer AnalystCommented:
What was the mistake?
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

David L. HansenProgrammer AnalystCommented:
Sorry, wrong post.  Ignore last.
0
David L. HansenProgrammer AnalystCommented:
What creates the XML file for you currently?  I've used XML and love it, however, the only time I've chosen to use it as my database was because the client insisted that no database tool be used (I wasn't very happy about that).  So, what I'm getting at is this, XML is a great way of describing data and transferring data, but it should not take the place of a database.  Your application has plenty of data and really ought to be managed in a database.  IMHO.

Recommendation:
I half suspect that you already have a database that is managing the test data for you.  If that's the case then I'd use it to generate the XML each time you make a change.  When changes are made by the user, update the database, then regenerate the XML and reload it into the application (it sounds slow but I think you'll be pleasantly surprised).  If your application is a far-flung distributed system where users have no access to your database, then we'll tackle the editing of the XML as you suggest.  How does that sound?
0
EdarnAuthor Commented:
Hi sl8rz!

There is unfourtanly no db currently. All testers have their own .xml files that they can chose to load. However I guess that as the xml file is modified correctly when a user choses to override a parameter. So your suggested solution would then be

TreeView.DataContext = null;
TreeView.Datacontext = modifiedXMLData

Open in new window


Is that correct? I guess this will remove the current selected item, but that could of course be stored away. I´ll try this.

I was more hopeing for an answer similar to the INotifyPropertyChanged which you can use when operating on a Class instead of an XML doc. :-)

kind regards
Thomas
0
David L. HansenProgrammer AnalystCommented:
Where do the XML document come from to start with?
0
EdarnAuthor Commented:
It´s either loaded from a .xml file stored on a local computer. Or it is generated dynamicly by drag and drop from a long list of cases/steps.
0
David L. HansenProgrammer AnalystCommented:
Did these xml files exist before this app was written?  If so, what created it?
0
EdarnAuthor Commented:
No. :) Are we not losing focus of the problem now. ;-)
0
David L. HansenProgrammer AnalystCommented:
Well, if there is a process that already exists which creates these xml files, then you could possibly feed it the new data and have it create a new xml document.  That way the xml document just becomes the carrier of the information instead of the database itself.

The issue is really concurrency.  If you have 10 people using this app and each one is maintaining their own xml data, then you run into a problem of keeping everyone up-to-date with accurate data.

I just want to make sure I understand you needs.
0
vbighamCommented:
You should be able to change the XmlDataProvider resource at runtime and specify the binding as DynamicResource instead of StaticResource.  This should get the ListBox to reevaluate the resource each time it is accessed.  If you need to trigger the listbox to update itself you can get the underlying BindingExpression on the dependency property you are using (ItemsSource in this case??) and call BindingExpression.UpdateTarget();

 
BindingExpression bindingExpression =
     System.Windows.Data.BindingOperations.GetBindingExpression(ListBox1, ListBox.ItemsSourceProperty);
bindingExpression.UpdateTarget();

Open in new window


This scenario seems an excellent candidate for the MVVM pattern.  The idea would be that the DataContext is a lightweight object that implements System.ComponentModel.INotifyPropertyChanged and raises the property changed event in the property setters for the items you are binding to.  Does that interest you at all?  Just a thought that it might be a more simple solution, but that is a broad topic and perhaps out of the current scope.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
EdarnAuthor Commented:
Thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.