[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

WPF ComboBox TwoWay binding with XML

Posted on 2013-12-19
21
Medium Priority
?
1,492 Views
Last Modified: 2014-02-04
Hi Experts,

I'm writing my first WPF form in VB.NET VS2012 (finally taking the leap to WPF) and have run into a problem.

I have a data file (XML)  that contains all the values for my comboboxes.

At run time, if the item the user needs is not in the list, I need them to be able to add it to the list and have it store in the xml file.

In the past I did that all programatically rather than using data binding, which I want to do now.

the line in the 3rd code block

cb.Items.Add(CustomInputBox.Text)

errors out with
"Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."

And there is my problem, not sure how to add it to the source.....
I'm also not sure the binding to the ComboBox is correct either, though it DOES display all the elements in the XML file.


Here's the important bits of my XAML:

<UserControl x:Class="FireControl"
             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"
             xmlns:WPFInputBox="clr-namespace:WPFInputBox;assembly=WPFInputBox"
             
             mc:Ignorable="d" Width="903" Height="842">
    <UserControl.Resources>
        <XmlDataProvider x:Key="Data" XPath="/Data" Source="pack://siteoforigin:,,,/Data/Data.xml"/>
    </UserControl.Resources>


    <Grid x:Name="MainGrid" HorizontalAlignment="Left" Height="842" VerticalAlignment="Top" Width="903">
        <Grid.Resources>
            <XmlDataProvider x:Key="Data" XPath="/Data" Source="pack://siteoforigin:,,,/Data/Data.xml"/>
        </Grid.Resources>
        
        <GroupBox Header="General Info" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="217" Width="238" FontWeight="Bold">
            <Grid>

                <Label Content="Type" HorizontalAlignment="Left" Margin="6,10,0,0" VerticalAlignment="Top" FontWeight="Normal"/>
                <ComboBox x:Name="Fire_Type" HorizontalAlignment="Left" Margin="96,10,0,0" VerticalAlignment="Top" Width="120" FontWeight="Normal"  ItemsSource="{Binding Source={StaticResource Data}, XPath=Type/Type, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" DisplayMemberPath="@id" />

'.....
</Grid>
</GroupBox>
<WPFInputBox:InputBox x:Name="CustomInputBox" Grid.ColumnSpan="2" Visibility="Collapsed" />
</Grid>
</UserControl>

Open in new window


XML Excerpt:
<Data>
  <Type>
    <Type id="[Add New Type]" />
    <Type id="Type 1" />
    <Type id="Type 2" />
    <Type id="Type 3" />
  </Type>
</Data>

Open in new window


Private Sub Fire_Type_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles Fire_Type.SelectionChanged

        Dim cb As ComboBox = DirectCast(sender, ComboBox)
        If cb.SelectedIndex = 0 Then
            ShowInputBox("Add New Type")
            If CustomInputBox.OK Then
                cb.Items.Add(CustomInputBox.Text) 
            End If
        End If
    End Sub

Open in new window

0
Comment
Question by:sgaggerj
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 8
21 Comments
 
LVL 1

Author Comment

by:sgaggerj
ID: 39731961
So I haven't been able to figure out two way databinding on the combo box, so I came up with the following:

I Changed the selection changed handler to

Private Sub Fire_Type_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles Fire_Type.SelectionChanged

        Dim cb As ComboBox = DirectCast(sender, ComboBox)
        If cb.SelectedIndex = 0 Then
            ShowInputBox("Add New Type")
            If CustomInputBox.OK Then
                Dim index As Integer = Fire_Type.Items.Count
                ' add new item to XML
                AddNewItemToXML("Type", CustomInputBox.Text)
                ' update the control source

                ' update the selected index
                'cb.SelectedIndex = index
            End If
        End If

Open in new window


and added

    Private Sub AddNewItemToXML(ByVal node As String, ByVal id As String)
        Dim d As New XmlDocument
        d.Load(DATA_FILE)

        Dim docroot As XmlNode = d.DocumentElement

        Dim root As XmlNode = docroot.SelectSingleNode(node)

        Dim child As XmlNode = d.CreateElement(node)

        Dim attribute As XmlAttribute = d.CreateAttribute("id")
        attribute.InnerText = id
        child.Attributes.Append(attribute)

        root.AppendChild(child)

        d.Save(DATA_FILE)


    End Sub

Open in new window


and that's where I'm at currently.

I now need to refresh the combobox source, and set the correct index on the combobox.

For right now, the item added will always be added at the end of the list.  I'll figure out sorting later if I decide it needs it.
0
 
LVL 13

Accepted Solution

by:
Ashok earned 2000 total points
ID: 39738044
You are doing this correctly in your post ID: 39731961.

You are supposed to add to XML directly.

You cannot add directly to ComboBox in this situation.

By the way, if you use ObservableCollection and add from XML to ObservableCollection, you would then add new item to ObservableCollection and it would refresh automatically.
0
 
LVL 13

Expert Comment

by:Ashok
ID: 39738095
' update the control source

cb.Items.Refresh()
0
Fill in the form and get your FREE NFR key NOW!

Veeam® is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.

 
LVL 1

Author Comment

by:sgaggerj
ID: 39738102
Thanks for the post! Good to know I was at least going in the right direction!

In my 2nd post, I added to XML directly and it works.

From what I can see, I have one of two options -

1) Continue that way, which would mean I need to refresh the binding of the combobox, and haven't found/figured out a way to do that

or

2) Use ObservableCollection as you mentioned, however I've never worked with observablecollection, and unsure where to start.  If, when using OC, I add something to the OC, does it a) add to the combobox (refresh) AND to XML?
 would you be able to provide a simple example?
0
 
LVL 1

Author Comment

by:sgaggerj
ID: 39738106

' update the control source

cb.Items.Refresh()

I had tried that after getting the new item added to XML, and it doesn't reload/refresh what was added to XML.
0
 
LVL 13

Expert Comment

by:Ashok
ID: 39738112
If, when using OC, I add something to the OC, does it a) add to the combobox (refresh) AND to XML?

a) Yes

b) No
0
 
LVL 1

Author Comment

by:sgaggerj
ID: 39738126
OK, so I would need to add to XML (as I'm doing) and to the OC.  Cool. good to know.

On to the OC, if you have any good/simple examples that'd be a huge help.  I'm googling now..
0
 
LVL 13

Expert Comment

by:Ashok
ID: 39738128
See answer in this post (it is in C#), but logic is same.

http://stackoverflow.com/questions/14506498/wpf-property-binding-doesnt-update-at-run-time
0
 
LVL 1

Author Comment

by:sgaggerj
ID: 39738142
Thanks!  

I was just reading through this:

http://www.telerik.com/help/wpf/gridview-loading-data-from-xml.html
0
 
LVL 13

Expert Comment

by:Ashok
ID: 39738145
I am at work and do not have .NET.
I will try to give you more help after I am home.

By the way, I code in C#.  Also, there is very good code converter at

http://converter.telerik.com/

HTH
Ashok
0
 
LVL 13

Expert Comment

by:Ashok
ID: 39738157
http://www.telerik.com/help/wpf/gridview-loading-data-from-xml.html

Above is good for loading data once, but it does not have PropertyChanged event which is what you need.
0
 
LVL 1

Author Comment

by:sgaggerj
ID: 39738160
No worries Ashok, I'm about to head home now anyhow and will be away for a few days.  

Any help you can give is greatly appreciated, and I can read/translate most C# on the fly as I'm somewhat versed in it, but still prefer VB as that's what I'm better at so C# code won't confuse me (too much!)

Thanks again!

And yea - I love that converter!
0
 
LVL 1

Author Comment

by:sgaggerj
ID: 39751311
OK, I'm back and ready to take on this.  Let me know what your thoughts on this were.

Thanks!
0
 
LVL 13

Expert Comment

by:Ashok
ID: 39763180
sgaggerj,

I do not know if / when I will have some free time to work on this.

Thanks,
Ashok
0
 
LVL 1

Author Comment

by:sgaggerj
ID: 39765072
No problem Ashok,

thanks for your help thus far - if you come across any examples in vb or c# that you think might help as well, let me know.  I'll go back and review the link you posted earlier

(http://stackoverflow.com/questions/14506498/wpf-property-binding-doesnt-update-at-run-time)

Thanks again!
0
 
LVL 1

Author Closing Comment

by:sgaggerj
ID: 39832560
Finally got a working system, unfortunately couldn't get the OC working but I wrote my own that seems to work.

Thanks!
0
 
LVL 13

Expert Comment

by:Ashok
ID: 39834154
Glad to hear that you got it working!

Thanks,
Ashok
0

Featured Post

Enroll in October's Free Course of the Month

Do you work with and analyze data? Enroll in October's Course of the Month for 7+ hours of SQL training, allowing you to quickly and efficiently store or retrieve data. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

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

Computer science students often experience many of the same frustrations when going through their engineering courses. This article presents seven tips I found useful when completing a bachelors and masters degree in computing which I believe may he…
If you are a mobile app developer and especially develop hybrid mobile apps then these 4 mistakes you must avoid for hybrid app development to be the more genuine app developer.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Starting up a Project

656 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