1
votes

I have a datagrid within a view

<Grid x:Name="LayoutRoot" Background="White" Width="600" MaxHeight="150">
    <sdk:DataGrid x:Name="grid1" ItemsSource="{Binding Persons}" SelectedItem="{Binding MyList, Mode=TwoWay}">
    </sdk:DataGrid>
</Grid>

Within my ViewModel I have the following code

private ObservableCollection<string> myList;
    public ObservableCollection<string> MyList
    {
        get { return myList; }
        set
        {
            myList = value;
            NotifyPropertyChanged(vm => vm.MyList);
        }

And for the DG

 private ObservableCollection<Person> person;    
    public ObservableCollection<Person> Persons
    {
        get { return person; }
        set
        {
            person = value;
            NotifyPropertyChanged(vm => vm.Persons);
        }
    }

I was hoping from the View I could bind the selected item(row) of the datagrid to the MyList collection within my view model (Maybe IList vs OC?). I only need one value from the selected row such as address or zip. But do I need to pass the entire collection of can I get just one cell value into the view model another way?

For example here is the class I am using to populate the data grid

        public void CreateList()
    {
        Person p = new Person();
        p.FirstName = "Bob";
        p.LastName = "Jones";
        p.Address = "123 Main Street";
        p.City = "Wilmington";
        p.State = "NC";
        p.Zip = "12345";


        Person p1 = new Person();
        p1.FirstName = "Sue";
        p1.LastName = "Smith";
        p1.Address = "1222 Main Street";
        p1.City = "Tampa";
        p1.State = "FL";
        p1.Zip = "12345";

        Person p2 = new Person();
        p2.FirstName = "Chris";
        p2.LastName = "Jones";
        p2.Address = "234 Water Street";
        p2.City = "Dallas";
        p2.State = "TX";
        p2.Zip = "22222";

        Person p3 = new Person();
        p3.FirstName = "Andy";
        p3.LastName = "Jones";
        p3.Address = "434 Main Street";
        p3.City = "Columbia";
        p3.State = "SC";
        p3.Zip = "12345";

        ObservableCollection<Person> Result = new ObservableCollection<Person>();
        Result.Add(p);
        Result.Add(p1);
        Result.Add(p2);
        Result.Add(p3);

        Persons = Result;          
    }

This class is fired when the view model is loaded. I would like to be able to select the third row of data and only pass the address value back to the VM. My inital thought was to pass the entire selected row back to the vm and then extract the address from that collection.

Using the selectedItem Binding does not work, selecting a row never triggers the inotify event in the vm so I know the collection is not being updated unless I click in the DG and then outside of it which only passes a null value. Secondly, is there a more effient way to do this vs. using the code behind to pull a value and then pass it to the VM? I had thought of using selection changed event within view and then set the column value to a bound field that is passed to the vm but this seems hacky.

Thanks for any suggestions or ideas.

-cheers

2

2 Answers

1
votes

It think you've thrown in a bit of a curve ball with this MyList property to which you want to "bind the selected item". Everywhere else, including your own solution, you refer to binding to a single item. So why have a property to receive it be a list type?

It seems to me that what you need is to drop the MyList and simply have:-

 private Person mySelectedItem;
 public Person SelectedItem
 {
      get
      {
          return mySelectedItem;
      }
      set
      {
          mySelectedItem = value;
          NotifyPropertyChanged("SelectedItem");
      }
 }

Now your binding on the DataGrid would make sense:-

<sdk:DataGrid x:Name="grid1" ItemsSource="{Binding Persons}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">   

And your TextBlock would look something like:-

  <TextBlock x:Name="textholder" Text="{Binding SelectedItem.FirstName}" /> 
0
votes

Update The current approach I am taking for this is within the code behind of the view I have the following

        private void grid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Person selectedPerson = grid1.SelectedItem as Person;
        textholder.Text = selectedPerson.Address;
    }

Then within the view I have a text field

 <TextBlock x:Name="textholder" Text="{Binding SelectedID, Mode=TwoWay}"/>

Which is bound to the SelectedID property within the VM

This works and gets the value to the VM. This just seems wierd in implementation (but it is a lot less code that using commands and command parameters :) ) . I'd welcome any other ideas.

-cheers