0

How to do binding with listview? I did class, I did collection I but when I do binding it doesn't work:

        public class DrawingVisualObject : DrawingVisual
       {
        public int Id { get; set; }
        public string Name { get; set; }
        public DrawingVisualObject(int id, string name)
        {
            Id = id;
            Name = name;
        }
    }

    ObservableCollection<DrawingVisualObject> mPointNames = new     ObservableCollection<DrawingVisualObject>();
    public MainWindow()
    {
        this.DataContext = mPointNames;
        InitializeComponent();
        lstv.ItemsSource = mPointNames;
    }

    public ObservableCollection<DrawingVisualObject> PointNames
    {
        get
        {
            return mPointNames;
        }
    }

This is xaml code which I wrote

<ListView MinHeight="350" ItemsSource="{Binding DrawingVisualObject, Mode=TwoWay}" Name="lstv">
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Name}"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Id}"/>

2 Answers2

1

You dont have to use DrawingVisual for binding. In your ViewModel or in your Model ceate class FooItem

public class FooItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public FooItem(int id, string name)
    {
        Id = id;
        Name = name;
    }
}

Then in your ViewModel create ObservableCollection

 public ObservableCollection<FooItem> PointNames
    {
        get
        {
            return mPointNames;
        }
    }

In your xaml use:

<ListView Margin="10" Name="FooItems" ItemsSource="{Binding Path=PointNames}">
        <ListView.View>
                <GridView>
                        <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
                        <GridViewColumn Header="Id" Width="50" DisplayMemberBinding="{Binding Id}" />
                </GridView>
        </ListView.View>
</ListView>

Than remove "lstv.ItemsSource = mPointNames;" from View constructor. In MVVM there should be only init call, maximally event handlers initialization.

Hope it helps

Clemens
  • 123,504
  • 12
  • 155
  • 268
Jakub Čermoch
  • 431
  • 1
  • 9
  • 20
  • Set the DataContext to an instance of the class that owns the PointNames property, i.e. the view model class. If MainWindow has the property, set DataContext = this. – Clemens Aug 21 '16 at 17:49
  • If it doesnt work, there is probably problem between View and DataContext. Clements is right. But be carefull when you use DataContext = this. It is against MVVM for good reason. If you have problem with binding, you can use converter in binding for debuging. Like in https://spin.atomicobject.com/2013/12/11/wpf-data-binding-debug/ – Jakub Čermoch Aug 21 '16 at 18:00
0

Your example doesnt look like MVVM, but if u want to have data in your code behind -- do it with dependency propertys.

Here is the example for the XAML

<Window x:Class="Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Test"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525"
    Name="myWindow">
<Grid>
          <ListView ItemsSource="{Binding ElementName=myWindow, Path=DrawingVisualCollection}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}"></GridViewColumn>
                <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Path=Id}"></GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

</Grid>

The code behind looks like this

namespace Test
{

public class DrawingVisualObject : DrawingVisual
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DrawingVisualObject(int id, string name)
    {
        Id = id;
        Name = name;
    }
}

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{

    public ObservableCollection<DrawingVisualObject> DrawingVisualCollection
    {
        get { return (ObservableCollection<DrawingVisualObject>)GetValue(DrawingVisualCollectionProperty); }
        set { SetValue(DrawingVisualCollectionProperty, value); }
    }

    // Using a DependencyProperty as the backing store for DrawingVisualCollection.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DrawingVisualCollectionProperty =
        DependencyProperty.Register("DrawingVisualCollection", typeof(ObservableCollection<DrawingVisualObject>), typeof(MainWindow), new PropertyMetadata(new ObservableCollection<DrawingVisualObject>()));

    public MainWindow()
    {
        InitializeComponent();

        List<DrawingVisualObject> sample = new List<DrawingVisualObject>();

        sample.Add(new DrawingVisualObject(1, "Yolo"));
        sample.Add(new DrawingVisualObject(2, "Swag"));

        this.FillCollection(sample);

    }

    public void FillCollection(IEnumerable<DrawingVisualObject> objects2fill)
    {
        this.DrawingVisualCollection.Clear();

        foreach(DrawingVisualObject obj in objects2fill)
        {
            this.DrawingVisualCollection.Add(obj);
        }
    }


}

}

This should work for you

Keep in mind: if u are initializing the Collection again, you may destroy the binding. I tried to show this at the example method FillCollection(). So this means if you are using MVVM you should allways set your ObservableCollection to private set.

I recommend you drop in at MVVM again more exactly. To know what is the common base for viewmodels is allways a good start!!!

Community
  • 1
  • 1
Peter
  • 1,655
  • 22
  • 44