locked
how to access an XAML control from code RRS feed

  • Question

  • i got a textbox control that for some reason I cannot set its text propertie from code. I think because it is part of data template but not sure. is there a way to access it. here is the XAML code.

    I need to change the UnitUsedTextBlock.Text . thank you

    <ListView x:Name="RouteResultsListView" ItemsSource="{Binding RouteLegs}" Width="400" Height="540" HorizontalAlignment="Left"   SelectionMode="None" ScrollViewer.VerticalScrollBarVisibility="Disabled">
                        <ListView.ItemTemplate>
                                    <DataTemplate >
                                        <ListBox  ItemsSource="{Binding ItineraryItems}" Height="499">
                                            <ListBox.ItemTemplate>
                                                <DataTemplate>
                                                    <StackPanel Orientation="Horizontal"  >
                                                            <TextBlock  Text="{Binding Instruction.Text}" 
                                                                   TextWrapping="Wrap" MaxLines="5" Width="200" />
                                                            <TextBlock Text="{Binding TravelDistance}" 
                                                                   Margin="10,0,0,0" />
                                                            <TextBlock x:Name="UnitUsedTextBlock" Margin="5,0,0,0" Text="km" />
                                                    </StackPanel>
                                                </DataTemplate>
                                            </ListBox.ItemTemplate>
                                        </ListBox>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>


    Monday, August 19, 2013 3:10 PM

Answers

  • I would use data binding to bind the Text property to a StaticResource that can be changed in the code behind.

    1. Add a class with INotifyProperty change interface to act as the container for Units (This class could be useful for other places in your application as well.)

        public class ViewModel : INotifyPropertyChanged
        {
            private string units;
            public string Units
            {
                get { return units; }
                set
                {
                    units = value;
                    RaisePropertyChanged();
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged([CallerMemberName] string caller = "")
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(caller));
                }
            }
        }

    2. Instantiate this class as a StaticResource in Page.Resources

        <Page.Resources>
            <local:ViewModel x:Key="myVM" />
        </Page.Resources>

    3. Add the data binding to your TextBlock in the DataTemplate

    <TextBlock Text="{Binding Units, Source={StaticResource myVM}}" Margin="5,0,0,0" />

    4. In the code behind, access the Units like this:

                var vm = this.Resources["myVM"] as ViewModel;
                vm.Units = "km";

    When you change vm.Units, the display will also change.

    Monday, August 19, 2013 4:18 PM
  • There are just a few concepts to work out:

    Data Binding and INotifyPropertyChanged are both covered in Data binding overview 

    StaticResources are covered in StaticResource markup extension.

    And accessing resources from code behind in ResourceDictionary and XAML resource references 

    For a more systematic study of these topics, I recommend Petzold, Programming Windows, 6th Edition.

    Of course, if you have any specific questions, post to the forum.


    • Edited by jrboddie Monday, August 19, 2013 8:12 PM
    • Marked as answer by Avichai-Rebibo Tuesday, August 20, 2013 11:03 AM
    Monday, August 19, 2013 8:12 PM
  • So, my suggestion to use a ListView and hide the buttons in the App bar is in line with the design philosophy for modern UI apps where you want your pages to show your data (content) without extraneous 'chrome' (buttons and redundant labels).  So with a simple approach, you don't have a delete button for each item.  It appears when you select an item and open the app bar.  

    If nothing is selected, your app bar only shows an add button.

    Here is an example:

    XAML

    <Page x:Name="page"
        x:Class="HelpWithListView.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:HelpWithListView"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    
            <ListView x:Name="WaypointList" Width="300" HorizontalAlignment="Left" VerticalAlignment="Top">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" Margin="20,0,0,0" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
    
            <!--This is the dialog box for adding and changing waypoints-->
            <Popup x:Name="EntryDialog" Width="300" HorizontalAlignment="Center" VerticalAlignment="Center">
                <StackPanel Background="#FF309501">
                    <TextBlock Style="{StaticResource SubheaderTextStyle}" Margin="20,10,0,0">Waypoint</TextBlock>
                    <TextBox x:Name="NewItem" Width="300" Margin="20,20,20,0"/>
                    <Button x:Name="DialogButton" Click="AddDialog_Click" Margin="0,20,20,10" HorizontalAlignment="Right">Add</Button>
                </StackPanel>
            </Popup>
    
        </Grid>
    
        <Page.BottomAppBar>
            <AppBar x:Name="myAppBar" Opened="AppBarOpened">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Orientation="Horizontal">
                        <Button Style="{StaticResource AddAppBarButtonStyle}" Click="Add_Click"/>
                        <Button x:Name="EditButton" Style="{StaticResource EditAppBarButtonStyle}" Click="Edit_Click" />
                        <Button x:Name="DeleteButton" Style="{StaticResource DeleteAppBarButtonStyle}" Click="Delete_Click"/>
                    </StackPanel>
                    <StackPanel Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal"/>
                </Grid>
            </AppBar>
        </Page.BottomAppBar>
    
    </Page>
    

    In order for the App bar buttons to appear, you must edit Common.StandardStyles.xaml and uncomment the styles for the three buttons that are used.  (Windows 8.1 makes this much easier!)

    Here is the code behind:

    using System.Collections.ObjectModel;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace HelpWithListView
    {
        public sealed partial class MainPage : Page
        {
            ObservableCollection<string> waypoints;
            public MainPage()
            {
                this.InitializeComponent();
                waypoints = new ObservableCollection<string>();
                //You can initialize items here
                waypoints.Add("hello");
                waypoints.Add("world");
                WaypointList.ItemsSource = waypoints;
            }
    
            //Open dialog popup for adding a new waypoint
            private void Add_Click(object sender, RoutedEventArgs e)
            {
                NewItem.Text = "";           
                DialogButton.Content = "Add";
                EntryDialog.IsOpen = true;
                NewItem.Focus(FocusState.Programmatic);
            }
    
            //Open dialog popup for changing a selected waypoint
            private void Edit_Click(object sender, RoutedEventArgs e)
            {
                var selectedIndex = WaypointList.SelectedIndex;
                NewItem.Text = waypoints[selectedIndex];
                DialogButton.Content = "Change";
                EntryDialog.IsOpen = true;
                NewItem.Focus(FocusState.Programmatic);
            }
    
            //Delete a selected waypoint
            private void Delete_Click(object sender, RoutedEventArgs e)
            {
                var selectedIndex = WaypointList.SelectedIndex;
                waypoints.RemoveAt(selectedIndex);
                WaypointList.Focus(FocusState.Unfocused);
                myAppBar.IsOpen = false;
            }
    
            //Use the same dialog box for adding and changing items
            private void AddDialog_Click(object sender, RoutedEventArgs e)
            {
                var context = DialogButton.Content as string;
                if (context == "Add")
                {
                     waypoints.Add(NewItem.Text);
                }
                else
                {
                    var selectedIndex = WaypointList.SelectedIndex;
                    waypoints[selectedIndex] = NewItem.Text;
                }
               
                EntryDialog.IsOpen = false;
                myAppBar.IsOpen = false;
            }
    
            //Only show the buttons that make sense when an item is selected.
            private void AppBarOpened(object sender, object e)
            {
                if (WaypointList.SelectedIndex >= 0)
                {
                    EditButton.Visibility = Visibility.Visible;
                    DeleteButton.Visibility = Visibility.Visible;
                }
                else
                {
                    EditButton.Visibility = Visibility.Collapsed;
                    DeleteButton.Visibility = Visibility.Collapsed;
                }
            }
        }
    
    }
    

    So when the add button in the app bar is clicked, a popup appears with a textbox that you can edit.  The popup button has an 'add' button to commit the content to your list.

    The change and delete buttons only appear in the App bar if something is selected.

    Friday, August 23, 2013 3:40 PM
  • here is the class with the changes

    public class Viapoints : INotifyPropertyChanged
    
        {
            private string _simpleAddress;
            private string civicNumber;
            private string civicName;
            private string civicCity;
            private string civicPostalCode;
            private string civicProvince;
            private string viaType;
    
           
            public Viapoints()
            { 
            
            
            }
    
            public Viapoints(string simpleAddress, string viatype)
            {
                this._simpleAddress = simpleAddress;
                this.ViaType = viatype;
    
    
            }
            public Viapoints(string cnumber, string cname, string ccity,string cpostalcode, string cprovince)
            {
                this.civicNumber = cnumber;
                this.civicName = cname;
                this.civicCity = ccity;
                this.civicPostalCode = cpostalcode;
                this.civicProvince = cprovince;
            }
    
            public string SimpleAddress
            {
                get { return _simpleAddress; }
                set { _simpleAddress = value;
                NotifyPropertyChanged();
                }
    
            }
            public string ViaType
            {
                get { return viaType; }
                set { viaType = value; }
    
            }
            public string CivicNumber
            {
                get { return civicNumber; }
                set { civicNumber = value; }
            }
    
            public string CivicName
            {
                get { return civicName; }
                set { civicName = value; }
            }
    
            public string CivicCity
            {
                get { return civicCity; }
                set { civicCity = value; }
            }
    
            public string CivicPostalCode
            {
                get { return civicPostalCode; }
                set { civicPostalCode = value; }
            }
    
            public string CivicProvince
            {
                get { return civicProvince; }
                set { civicProvince = value; }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
           
        }

    • Marked as answer by Avichai-Rebibo Saturday, August 31, 2013 1:33 PM
    Saturday, August 31, 2013 1:06 AM
  • Great.  The ObservableCollection will notify the UI of any additions or deletions.  It will also notify if an element is completely replaced as in the simple example that I made using a string element.

    When it is holding a more complex object like your Viapoints, a change to a property of an object in the collection does not cause the ObservableCollection to notify.  So the solution is to make the object able to notify when one of its properties change.

    • Marked as answer by Avichai-Rebibo Saturday, August 31, 2013 1:33 PM
    Saturday, August 31, 2013 2:10 AM
  • I suggest using a TextBlock to show the abbreviation in this case.

    The element would look something like this (assuming correct spelling of Abbreviation everywhere):

    <TextBlock Text="{Binding SelectedItem.Abbreviation, ElementName=Country}" />

    Of course, the  Country ComboBox ItemsSource is connected to the output of your deserializer.
    • Edited by jrboddie Sunday, September 1, 2013 3:46 PM
    • Marked as answer by Avichai-Rebibo Monday, September 2, 2013 11:49 AM
    Sunday, September 1, 2013 3:45 PM

All replies

  • I would use data binding to bind the Text property to a StaticResource that can be changed in the code behind.

    1. Add a class with INotifyProperty change interface to act as the container for Units (This class could be useful for other places in your application as well.)

        public class ViewModel : INotifyPropertyChanged
        {
            private string units;
            public string Units
            {
                get { return units; }
                set
                {
                    units = value;
                    RaisePropertyChanged();
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged([CallerMemberName] string caller = "")
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(caller));
                }
            }
        }

    2. Instantiate this class as a StaticResource in Page.Resources

        <Page.Resources>
            <local:ViewModel x:Key="myVM" />
        </Page.Resources>

    3. Add the data binding to your TextBlock in the DataTemplate

    <TextBlock Text="{Binding Units, Source={StaticResource myVM}}" Margin="5,0,0,0" />

    4. In the code behind, access the Units like this:

                var vm = this.Resources["myVM"] as ViewModel;
                vm.Units = "km";

    When you change vm.Units, the display will also change.

    Monday, August 19, 2013 4:18 PM
  • Wow working perfect. Now since I am a very beginner programming c#, Where do I start understanding what the code means ? and how exactly it works? Or maybe its too complicated for a beginner to understand. Maybe I will start using the same code for other needs then one day I will try to understand it lol.

    Thank you

    Monday, August 19, 2013 6:19 PM
  • There are just a few concepts to work out:

    Data Binding and INotifyPropertyChanged are both covered in Data binding overview 

    StaticResources are covered in StaticResource markup extension.

    And accessing resources from code behind in ResourceDictionary and XAML resource references 

    For a more systematic study of these topics, I recommend Petzold, Programming Windows, 6th Edition.

    Of course, if you have any specific questions, post to the forum.


    • Edited by jrboddie Monday, August 19, 2013 8:12 PM
    • Marked as answer by Avichai-Rebibo Tuesday, August 20, 2013 11:03 AM
    Monday, August 19, 2013 8:12 PM
  • After reading the above links the code makes better sense. i will continue digging in the links further more. Thanks

    Tuesday, August 20, 2013 11:02 AM
  • Another question for you geniuses,

    I made a methods that create a stackpanel and some buttons, text, textboxes......

    so basically everytime the user clicks the add button it adds a stackpanel in a parent one and adds the textboxes..

    This is done with a simple method. the problem is how do I access this xaml items later on in the program, as I understood all the xaml controls are in some kind of a collection. what I would like is change the text button Way point 1:  and the one Waypoint 2 and then the  Waypoint 3: and change the numbers 1,2,3 depending on which - button I press. So everytime the user deletes one of the waypoints then the numbert changes in the textblock depending of its position. woof does it make sense ?. here is the code for adding the controls and then the one for deleting the controls.

    Add the controls " I am sure this could be done in some kind of a class, but not sure how"

    -----------------------

    private void AddWaypointsButton_Click(object sender, RoutedEventArgs e)
            {
                
                if (AddWaypointCounter < 3)
                {
                    StackPanel _StackPanel = new StackPanel();
                    _StackPanel.Orientation = Orientation.Horizontal;
    
                    UIElementCollection stk1 = RouteInputStackpanel.Children;
                    TextBlock _TextBlock = new TextBlock();
                    _TextBlock.Text = "Way point " + (stk1.Count + 1).ToString() + " :";
                    _TextBlock.FontSize = 18;
                    _TextBlock.Margin = new Thickness(10, 15, 0, 0);
                    _TextBlock.FontFamily = new FontFamily("Arial");
                    _TextBlock.Foreground = new SolidColorBrush(Colors.Blue);
    
                    //TextBox _ViaTextBox = new TextBox();
                    TextBox _ViaTextBox = new TextBox();
                    _ViaTextBox.Width = 235;
                    _ViaTextBox.Margin = new Thickness(11, 10, 0, 0);
    
    
                    Button _ButtonRemove = new Button();
                    _ButtonRemove.Content = "-";
                    _ButtonRemove.Foreground = new SolidColorBrush(Colors.Black);
                    _ButtonRemove.Margin = new Thickness(11, 10, 0, 0);
    
                    RouteInputStackpanel.Children.Add(_StackPanel);
                    _StackPanel.Children.Add(_TextBlock);
                    _StackPanel.Children.Add(_ViaTextBox);
                    _StackPanel.Children.Add(_ButtonRemove);
    
                    _ViaTextBox.Name = "Via_" + stk1.Count.ToString();
                    _ButtonRemove.Name = "RemoveWaypointButton" + "_" + stk1.Count.ToString();
                    _ButtonRemove.Click += _ButtonRemove_Click;
                    _ViaTextBox.LostFocus += _ViaTextBox_LostFocus;
                    AddWaypointCounter++;
                }
                else
                {
                    AddWaypointsButton.IsEnabled = false;
                }
            }

    delete a control

    -------------------

    private void _ButtonRemove_Click(object sender, RoutedEventArgs e)
            {
                AddWaypointCounter--;
                Button buttonClick = sender as Button;
                StackPanel removeStackpanel = buttonClick.Parent as StackPanel;
                StackPanel RouteInputStackpanel = removeStackpanel.Parent as StackPanel;
                RouteInputStackpanel.Children.Remove(removeStackpanel);
                AddWaypointsButton.IsEnabled = true;
            }

    this basicly adds XAML items  and delete them. maybe this should be done in another way such as creating a observable collection and adding the items then accessing them from there. Not sure how to do that.

    Thanks for any help

    Thursday, August 22, 2013 11:21 PM
  • My approach would be to use a ListView that is bound to an observable collection.  The items template would show each waypoint in a simple TextBlock.  I would put editing controls in the App bar: Add, Edit and Delete selected ListView items.  What are the waypoints? Lat/Long? Cities? Airports? VORs?
    Thursday, August 22, 2013 11:45 PM
  • addresses
    Friday, August 23, 2013 12:13 AM
  • So, my suggestion to use a ListView and hide the buttons in the App bar is in line with the design philosophy for modern UI apps where you want your pages to show your data (content) without extraneous 'chrome' (buttons and redundant labels).  So with a simple approach, you don't have a delete button for each item.  It appears when you select an item and open the app bar.  

    If nothing is selected, your app bar only shows an add button.

    Here is an example:

    XAML

    <Page x:Name="page"
        x:Class="HelpWithListView.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:HelpWithListView"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    
            <ListView x:Name="WaypointList" Width="300" HorizontalAlignment="Left" VerticalAlignment="Top">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" Margin="20,0,0,0" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
    
            <!--This is the dialog box for adding and changing waypoints-->
            <Popup x:Name="EntryDialog" Width="300" HorizontalAlignment="Center" VerticalAlignment="Center">
                <StackPanel Background="#FF309501">
                    <TextBlock Style="{StaticResource SubheaderTextStyle}" Margin="20,10,0,0">Waypoint</TextBlock>
                    <TextBox x:Name="NewItem" Width="300" Margin="20,20,20,0"/>
                    <Button x:Name="DialogButton" Click="AddDialog_Click" Margin="0,20,20,10" HorizontalAlignment="Right">Add</Button>
                </StackPanel>
            </Popup>
    
        </Grid>
    
        <Page.BottomAppBar>
            <AppBar x:Name="myAppBar" Opened="AppBarOpened">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Orientation="Horizontal">
                        <Button Style="{StaticResource AddAppBarButtonStyle}" Click="Add_Click"/>
                        <Button x:Name="EditButton" Style="{StaticResource EditAppBarButtonStyle}" Click="Edit_Click" />
                        <Button x:Name="DeleteButton" Style="{StaticResource DeleteAppBarButtonStyle}" Click="Delete_Click"/>
                    </StackPanel>
                    <StackPanel Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal"/>
                </Grid>
            </AppBar>
        </Page.BottomAppBar>
    
    </Page>
    

    In order for the App bar buttons to appear, you must edit Common.StandardStyles.xaml and uncomment the styles for the three buttons that are used.  (Windows 8.1 makes this much easier!)

    Here is the code behind:

    using System.Collections.ObjectModel;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace HelpWithListView
    {
        public sealed partial class MainPage : Page
        {
            ObservableCollection<string> waypoints;
            public MainPage()
            {
                this.InitializeComponent();
                waypoints = new ObservableCollection<string>();
                //You can initialize items here
                waypoints.Add("hello");
                waypoints.Add("world");
                WaypointList.ItemsSource = waypoints;
            }
    
            //Open dialog popup for adding a new waypoint
            private void Add_Click(object sender, RoutedEventArgs e)
            {
                NewItem.Text = "";           
                DialogButton.Content = "Add";
                EntryDialog.IsOpen = true;
                NewItem.Focus(FocusState.Programmatic);
            }
    
            //Open dialog popup for changing a selected waypoint
            private void Edit_Click(object sender, RoutedEventArgs e)
            {
                var selectedIndex = WaypointList.SelectedIndex;
                NewItem.Text = waypoints[selectedIndex];
                DialogButton.Content = "Change";
                EntryDialog.IsOpen = true;
                NewItem.Focus(FocusState.Programmatic);
            }
    
            //Delete a selected waypoint
            private void Delete_Click(object sender, RoutedEventArgs e)
            {
                var selectedIndex = WaypointList.SelectedIndex;
                waypoints.RemoveAt(selectedIndex);
                WaypointList.Focus(FocusState.Unfocused);
                myAppBar.IsOpen = false;
            }
    
            //Use the same dialog box for adding and changing items
            private void AddDialog_Click(object sender, RoutedEventArgs e)
            {
                var context = DialogButton.Content as string;
                if (context == "Add")
                {
                     waypoints.Add(NewItem.Text);
                }
                else
                {
                    var selectedIndex = WaypointList.SelectedIndex;
                    waypoints[selectedIndex] = NewItem.Text;
                }
               
                EntryDialog.IsOpen = false;
                myAppBar.IsOpen = false;
            }
    
            //Only show the buttons that make sense when an item is selected.
            private void AppBarOpened(object sender, object e)
            {
                if (WaypointList.SelectedIndex >= 0)
                {
                    EditButton.Visibility = Visibility.Visible;
                    DeleteButton.Visibility = Visibility.Visible;
                }
                else
                {
                    EditButton.Visibility = Visibility.Collapsed;
                    DeleteButton.Visibility = Visibility.Collapsed;
                }
            }
        }
    
    }
    

    So when the add button in the app bar is clicked, a popup appears with a textbox that you can edit.  The popup button has an 'add' button to commit the content to your list.

    The change and delete buttons only appear in the App bar if something is selected.

    Friday, August 23, 2013 3:40 PM
  • Thank you looks nice.
    Sunday, August 25, 2013 7:14 PM

  • I of course changed the code because I want to experiment and learn, I get this problem that the WaypointList listview doesn't update when I try to edit one of the items. the adding and deleting part works perfectly.

    basically what I did is create a class that will hold the data and then add waypoints using the class.

    here is the code for only the edit part and the XAML. if needed other parts please let me know.

    Thank you

    XAML

    --------------

     <ListView x:Name="WaypointList" ManipulationDelta="ListViewManipulationDelta"  Background="#33309501" BorderBrush="#FF309501" 
                      BorderThickness="2" ManipulationMode="All" Visibility="Collapsed" Header="Route addresses"  HorizontalAlignment="Right"
                      VerticalAlignment="Center">
               <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" Width="Auto">
                            <TextBlock Text="{Binding Path=ViaType}" FontWeight="Bold" Margin="10,0,0,0" FontSize="18" Foreground="Black" />
                            <TextBlock Text="{Binding Path=SimpleAddress}" Margin="20,0,0,0" FontWeight="Bold" FontSize="18" Foreground="Black"  />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <ListView.RenderTransform>
                    <TranslateTransform />
                </ListView.RenderTransform>
            </ListView>

    here is the edit part

    -------------------------

    private void Edit_Click(object sender, RoutedEventArgs e)
            {
                var selectedIndex = WaypointList.SelectedIndex;
                NewItem.Text = WayPoints[selectedIndex].SimpleAddress;
                DialogButton.Content = "Change";
                EntryDialog.IsOpen = true;
                
                NewItem.Focus(FocusState.Programmatic);
    
            }

    here is how I instantiate the class

     ObservableCollection<Viapoints> WayPoints;
    
            public MainPage()
            {            
                this.InitializeComponent();    
                WayPoints = new ObservableCollection<Viapoints>();
                WaypointList.ItemsSource = WayPoints;
    
            }

    the edit is actually happening in the class but not in the listview

    I hope it has some sense.

    thank you


    Friday, August 30, 2013 8:33 PM
  • OK.  Since it appears that your Waypoints (ViaPoints) are not simple strings, you may need to make ViaPoints class implement INotifyPropertyChanged.  Would you please post the ViaPoints class and the event handler that you are using for the button in the dialog box?
    Saturday, August 31, 2013 12:17 AM
  • Ok I got it fixed thanks to you. here is what I found

    http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2

    I implemented the INotifyPropertyChanged

    working perfect now.

    sweet

    Saturday, August 31, 2013 1:05 AM
  • here is the class with the changes

    public class Viapoints : INotifyPropertyChanged
    
        {
            private string _simpleAddress;
            private string civicNumber;
            private string civicName;
            private string civicCity;
            private string civicPostalCode;
            private string civicProvince;
            private string viaType;
    
           
            public Viapoints()
            { 
            
            
            }
    
            public Viapoints(string simpleAddress, string viatype)
            {
                this._simpleAddress = simpleAddress;
                this.ViaType = viatype;
    
    
            }
            public Viapoints(string cnumber, string cname, string ccity,string cpostalcode, string cprovince)
            {
                this.civicNumber = cnumber;
                this.civicName = cname;
                this.civicCity = ccity;
                this.civicPostalCode = cpostalcode;
                this.civicProvince = cprovince;
            }
    
            public string SimpleAddress
            {
                get { return _simpleAddress; }
                set { _simpleAddress = value;
                NotifyPropertyChanged();
                }
    
            }
            public string ViaType
            {
                get { return viaType; }
                set { viaType = value; }
    
            }
            public string CivicNumber
            {
                get { return civicNumber; }
                set { civicNumber = value; }
            }
    
            public string CivicName
            {
                get { return civicName; }
                set { civicName = value; }
            }
    
            public string CivicCity
            {
                get { return civicCity; }
                set { civicCity = value; }
            }
    
            public string CivicPostalCode
            {
                get { return civicPostalCode; }
                set { civicPostalCode = value; }
            }
    
            public string CivicProvince
            {
                get { return civicProvince; }
                set { civicProvince = value; }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
           
        }

    • Marked as answer by Avichai-Rebibo Saturday, August 31, 2013 1:33 PM
    Saturday, August 31, 2013 1:06 AM
  • Great.  The ObservableCollection will notify the UI of any additions or deletions.  It will also notify if an element is completely replaced as in the simple example that I made using a string element.

    When it is holding a more complex object like your Viapoints, a change to a property of an object in the collection does not cause the ObservableCollection to notify.  So the solution is to make the object able to notify when one of its properties change.

    • Marked as answer by Avichai-Rebibo Saturday, August 31, 2013 1:33 PM
    Saturday, August 31, 2013 2:10 AM
  • what do you recommend I do if I want to populate a list box with countries states/provinces ?

    what I want is the user to select what default country state/province the search will be based on.

    Saturday, August 31, 2013 1:29 PM
  • If the user will interact with this listbox infrequently, then I would put it in a Settings flyout in Charms.  If it is something that the user may frequently need to access, then I would add a 'Filter' button in the App bar that would call up a flyout that contains the listbox.
    Saturday, August 31, 2013 2:41 PM
  • yes this I have done but my question is what do you think is the correct way to populate the list box. create some kind of XML with the country states or some kind of an array. I think I can create some kind of an array with the states and abreviations. but maybe it would be nice to learn how to read an xml file to a class and then read the states. If you got some links that show how to do that would be great.

    thanks

    Saturday, August 31, 2013 3:32 PM
  • The topic you want to search for is XML Serialize/Deserialize.  It is the process of converting a object to XML and back.

    Here is an example that I cooked up:

    The XML File

    <?xml version="1.0" encoding="utf-8" ?>
    <LocationInfo>
      <Countries>
        <Country>
          <Name>Canada</Name>
          <States>
            <State>
              <Name>Alberta</Name>
            </State>
            <State>
              <Name>British Colombia</Name>
            </State>
            <State>
              <Name>Manitoba</Name>
            </State>
          </States>
        </Country>
        <Country>
          <Name>Mexico</Name>
          <States>
            <State>
              <Name>Aguascalientes</Name>
            </State>
            <State>
              <Name>Baja California</Name>
            </State>
            <State>
              <Name>Baja California Sur</Name>
            </State>
          </States>
        </Country>
        <Country>
          <Name>USA</Name>
          <States>
            <State>
              <Name>Alabama</Name>
            </State>
            <State>
              <Name>Alaska</Name>
            </State>
            <State>
              <Name>Arizona</Name>
            </State>
          </States>
        </Country>
      </Countries>
    </LocationInfo>
    


    The classes that represent the data

        public class LocationInfo
        {
            public List<Country> Countries { get; set; }
        }
    
        public class Country
        {
            public string Name { get; set; }
            public List<State> States { get; set; }
        }
    
        public class State
        {
            public string Name { get; set; }
        }


    A couple of ComboBoxes to select the data

            <StackPanel Width="200" HorizontalAlignment="Left" VerticalAlignment="Top">
                <ComboBox x:Name="Country" DisplayMemberPath="Name" />
                <ComboBox x:Name="State" Margin="0,20,0,0" ItemsSource="{Binding SelectedItem.States, ElementName=Country}" DisplayMemberPath="Name" />           
            </StackPanel>

    And a method to read the xml file, deserialize it and connect it to the ComboBoxes

        public sealed partial class MainPage : Page
        {
            LocationInfo locations;
            public MainPage()
            {
                this.InitializeComponent();
                initialize();
            }
    
            async void initialize()
            {
                var statesFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///States.xml"));
    
                //Deserialize xml data to object
                XmlSerializer xs = new XmlSerializer(typeof(LocationInfo));
                using (Stream stream = await statesFile.OpenStreamForReadAsync())
                {
                    locations = xs.Deserialize(stream) as LocationInfo;
                }
                Country.ItemsSource = locations.Countries;        
            }
        }

    The Country ComboBox ItemsSource is connected to the Countries list in the locations object.  In the XAML, it is set to show the Name property.

    The states ComboBox ItemsSource is bound to the States property of the SelectedItem of the County ComboBox and its display path is also set to Name.

    Saturday, August 31, 2013 5:05 PM
  • I am trying to add an abbreviation for each country. I cant seem to bind it correctly to another listbox. here is the codei used.

    just a sample of the XML

    <?xml version="1.0" encoding="utf-8" ?>
    <LocationInfo>
      <Countries>
        <Country>
          <Abreviation>AF</Abreviation>
          <Name>Afghanistan</Name>
          <States>
            <State>
              <Name>AA</Name>
            </State>
          </States>
        </Country>
        <Country>
          <Abreviation>AL</Abreviation>
          <Name>Albania</Name>
          <States>
            <State>
              <Name>AA</Name>
            </State>
          </States>
        </Country>

    the class I modified. not sure it is correct

     public class Country
        {
            public string Abreviation { get; set; }
            public string Name { get; set; }
            public List<State> States { get; set; }
        }
    
        public class State
        {
            public string Name { get; set; }
        }
    
        public class Ab
        {
            public string Abreviation { get; set; }
        }
    

    here is the XAML

    <StackPanel Style="{StaticResource SettingsFlyoutSectionStyle}">
                <TextBlock Text="Default region" Style="{StaticResource TitleTextBlockStyle}"/>
                <TextBlock Margin="0,0,0,25" Text="Select the default region." Style="{StaticResource BodyTextBlockStyle}"/>
                <ComboBox x:Name="Country" DisplayMemberPath="Name"  Width="200" HorizontalAlignment="Left" />
                <ComboBox x:Name="State" ItemsSource="{Binding SelectedItem.States, ElementName=Country}" DisplayMemberPath="Name"   Width="200" HorizontalAlignment="Left" />
                <ComboBox x:Name="Abreviation" ItemsSource="{Binding SelectedItem.Country, ElementName=Abreviation}"  DisplayMemberPath="Abreviation" Width="200" HorizontalAlignment="Left" />
    
            </StackPanel>

    Sunday, September 1, 2013 1:30 AM
    • You don't need the Ab class.
    • Inside your code, you've misspelled Abbreviation
    • I don't see where you are going with your UI.  I would select the country by name or abbreviation but not both.

    By the way, this thread is getting pretty long and I think the moderators prefer one question per thread.

    Sunday, September 1, 2013 3:36 AM
  • Good morning

    I am just trying to understand the way the deserialization work. for some reason I cannot get the Abreviation to show up depending on what country was selected.

    the only way I can see anything in the listbox is if I add this code

     Abbreviation.ItemsSource = locations.Countries;

    but it show th whole abbreviated list. I just need it to show the appropriate Abbreviation for the country chosen.

    Thank you

    Sunday, September 1, 2013 12:49 PM
  • I suggest using a TextBlock to show the abbreviation in this case.

    The element would look something like this (assuming correct spelling of Abbreviation everywhere):

    <TextBlock Text="{Binding SelectedItem.Abbreviation, ElementName=Country}" />

    Of course, the  Country ComboBox ItemsSource is connected to the output of your deserializer.
    • Edited by jrboddie Sunday, September 1, 2013 3:46 PM
    • Marked as answer by Avichai-Rebibo Monday, September 2, 2013 11:49 AM
    Sunday, September 1, 2013 3:45 PM