Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

C# Bindings with WPF and XML files

Posted on 2011-10-19
13
Medium Priority
?
1,016 Views
Last Modified: 2013-11-12
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


0
Comment
Question by:Edarn
  • 7
  • 5
13 Comments
 
LVL 15

Expert Comment

by:David L. Hansen
ID: 37001616
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
 

Author Comment

by:Edarn
ID: 37003060
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
 
LVL 15

Expert Comment

by:David L. Hansen
ID: 37003783
What was the mistake?
0
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 
LVL 15

Expert Comment

by:David L. Hansen
ID: 37003790
Sorry, wrong post.  Ignore last.
0
 
LVL 15

Expert Comment

by:David L. Hansen
ID: 37007129
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
 

Author Comment

by:Edarn
ID: 37016376
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
 
LVL 15

Expert Comment

by:David L. Hansen
ID: 37018412
Where do the XML document come from to start with?
0
 

Author Comment

by:Edarn
ID: 37020247
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
 
LVL 15

Expert Comment

by:David L. Hansen
ID: 37020761
Did these xml files exist before this app was written?  If so, what created it?
0
 

Author Comment

by:Edarn
ID: 37021060
No. :) Are we not losing focus of the problem now. ;-)
0
 
LVL 15

Expert Comment

by:David L. Hansen
ID: 37021337
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
 
LVL 7

Accepted Solution

by:
vbigham earned 2000 total points
ID: 37025004
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
 

Author Closing Comment

by:Edarn
ID: 37044768
Thanks!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question