Click here to Skip to main content
15,904,986 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi All,

The dilemma is as follows:

There is a base class and then there are two windows. The first window is the owner. This window is passive containing a listview and is linked to the next window while the next window holds other controls and also a similar listview as well. Both windows are bound to the same observable collection but the second window is the only one that gets updated from the observable collection per operation. The first does not update unless reloaded or restarted.

How can I get the updates on the first window at the same time as that on the second?

The window has a datacontext property as follows
DataContext="{Binding RelativeSource={RelativeSource self}}"                    


The code for the listview is as follows

XML
<ListView Name="interface_ListView" ItemsSource="{Binding interfaceList}">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="64" Header="Port"
                                DisplayMemberBinding="{Binding portValue}" />
                            <GridViewColumn Width="150" Header="Type"
                                DisplayMemberBinding="{Binding portType}" />
                            <GridViewColumn Width="180" Header="Description"
                                DisplayMemberBinding="{Binding deviceDescription}" />
                            <GridViewColumn Width="64" Header="Vlan"
                                DisplayMemberBinding="{Binding vlanNumber}" />
                        </GridView>
                    </ListView.View>
                </ListView>



Thanks
Posted
Updated 9-Jun-11 20:46pm
v2
Comments
User-Rock 10-Jun-11 2:27am    
Are you using ViewModel for it?
Your two windows should bind to common viewModel object having observableCollection list as property.
This will solve problem.
Member 7796817 10-Jun-11 12:10pm    
Actually the base class has the observable Collection as property and the two windows inherit such from the base class.

1> Create a Common view model class with ObservableCollection<> list property.
C#
public class CommonViewModel : INotifyPropertyChanged
{
    private ObservableCollection<string> items;
    public ObservableCollection<string> Items
    {
        get
        {
            return items;
        }
        set
        {
            items = value;
            OnPropertychanged("Items");
        }
    }

    private void OnPropertychanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}


2> Pass the same instance of above view model class to both windows as data context.
E.g.
C#
public partial class Window1 : Window
  {
      public Window1()
      {
          InitializeComponent();
          CommonViewModel vm = new CommonViewModel();
          vm.Items = new ObservableCollection<string>(){"First","Second"};
          this.DataContext = vm;
          Window2 w2 = new Window2();
          w2.DataContext = vm;
          vm.Items.Add("Three");
          w2.Show();
      }
  }

XML
<Window x:Class="DummyWPF.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Grid>
        <ListView ItemsSource="{Binding Items}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Label Content="{Binding}"></Label>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>



XML
<Window x:Class="DummyWPF.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window2" Height="300" Width="300">
    <Grid>
        <ListView ItemsSource="{Binding Items}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Label Content="{Binding}"></Label>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>



3> You then can modify anywhere you want, both windows will get update as both are bound to same property throught common view model.
 
Share this answer
 
v3
Comments
Sergey Alexandrovich Kryukov 10-Jun-11 16:42pm    
Looks pretty good, my 5, but I think my solution is more general and more clean, no ad-hoc programming and additional access.

Please see.
--SA
Tarun.K.S 10-Jun-11 17:18pm    
Excellent answer Rakesh going by the WPF way. My 5
This is a more general approach based on appropriate interface implemented by a window class.

Create some interface which should accept some data to use for the ListView update. It would be the best if this interface is about pure data, unaware of any UI controls. Make this interface visible by both of your Windows classes. Implemented this interface with the Window containing the ListView in question using data passed through interface to update the list view. Pass the interface reference to another window (make a property of interface type), but not the reference to the instance of the Window itself. This way, you do not make any access specifiers more open then it's really needed.

In the implementation of interface, the partial windows declaration in a separate file is a great help. Note that in different partial declarations you don't need to list all the base classes and interface, so you can create a separate file, write a partial declaration with the interface in inheritance list, nothing else. You don't have to modify other files where the same class is defined.

—SA
 
Share this answer
 
I thank both contributors for the effort and what I currently have seems to be within the lines of the above mentioned solutions. Let me elaborate...

My base class is similar to:
XML
public class BaseClass : Window
{        
        public ObservableCollection<Item> _itemList = new ObservableCollection<Item>();
               
        public ObservableCollection<Item> itemList
        { get { return _vlanList; } }
}

and have a class (in this case "Item") listed synonymous to:
C#
public class Item
{
        public string type { get; set; }
        public string name { get; set; }
}

then Window1 displays a listview that holds details of items that are added to the listview through Window2.

Window1.cs is as such:
C#
public partial class Window1 : BaseClass
{
        public Window1()
        {
            //Deserializer(filePath);
            InitializeComponent();           
        }
}

Window1.xaml.cs ->
XML
<ListView Name="interface_ListView" ItemsSource="{Binding itemList}">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="64" Header="Name"
                                DisplayMemberBinding="{Binding name}" />
                            <GridViewColumn Width="150" Header="Type"
                                DisplayMemberBinding="{Binding type}" />
                        </GridView>
                    </ListView.View>
                </ListView>

Window2 is synonymous to Window1 in its inheritance and listview, but the operations are performed here such as:
C#
_itemList.Add(new Item
            {
                name = text_Name.Text,
                type = text_Type.Text
            });

With the above description, Window2 is updated since the operations are carried out from that window, however Window1 stays dormant until refreshed/reloaded (which is possible for the data to be retrieved since it is serialized and deserialized from an xml datafile). Both windows reference the observable collection from the base window and have the datacontext of relativesource set to "self" (perhaps the issue lies there).

Thanks
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900