tags:

views:

65

answers:

5

i try to use generate MVVM pattern using Silverlight ListView. But if i bind data my silverlight control no data visualize. also no error return. i see empty gridview.

Model:

MyData.cs


 public class MyData
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Price { get; set; }
        public string Author { get; set; }
        public string Catalog { get; set; }
    }

View:

BookViewer.xaml


<UserControl x:Class="wpf.MVVM.Project.View.BookViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="500" Width="700">
    <Grid>
        <StackPanel>
            <ListView Margin="8" Height="400" Width="650" ItemsSource="{Binding Path=MyData}">
         <ListView.View>
                    <GridView >
                        <GridViewColumn Header="ID" Width="Auto">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding ID}" TextAlignment="Right" Width="40"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" Width="100"/>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=Price}" Header="Price" Width="100"/>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=Author}" Header="Author" Width="100"/>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=Catalog}" Header="Catalog" Width="100"/>
                    </GridView>
                </ListView.View>
            </ListView>
        </StackPanel>
    </Grid>
</UserControl>

ViewModel:

MyDataViewModel.cs


  public class MyDataViewModel
    {
       // public ObservableCollection<MyData> myData { get; set; }
        public List<MyData> GetData()
        {
            List<MyData> myDataList = new List<MyData>();
            myDataList.Add(new MyData() { ID = 1, Name = "yusuf karatoprak", Author = "Mike Gold", Price = "6.7 TL", Catalog = "IT" });
            myDataList.Add(new MyData() { ID = 2, Name = "yusuf karatoprak", Author = "Scott Gunitella", Price = "9.7 TL", Catalog = "IT" });
            myDataList.Add(new MyData() { ID = 3, Name = "yusuf karatoprak", Author = "David Hayden", Price = "11.7 TL", Catalog = "IT" });
            if (myDataList.Count > 0)
            {
                return myDataList;
            }
            else
                return null;
        }

    }

Window1.xaml

  public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            MyDataViewModel myDataCtx = new MyDataViewModel();
            MyDataDataView.DataContext = myDataCtx.GetData();
        }
    }

<Window x:Class="wpf.MVVM.Project.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="1000" Width="900"
    xmlns:views="clr-namespace:wpf.MVVM.Project.View" Loaded="Window_Loaded">
    <Grid>
        <views:BookViewer x:Name="MyDataDataView" Margin="0,0,0,0"></views:BookViewer>
    </Grid>
</Window>

i writed these codes but no data i can see.Look below:

alt text

i added 2 pics my debug mode:

alt text alt text

A: 

Try using an ObservableCollection<MyData>instead of a regular List<T>. Because the binding occurs before the list is filled, it is not notified of changes in the list.
The ObservableCollection does give notifications to the Binding when an item is added.

Roel
public ObservableCollection<MyData> GetData() { ObservableCollection<MyData> myDataList = new ObservableCollection<MyData>();
Phsika
i writed these codes but no data return again...
Phsika
It seems I missed the bug, Isak Savo did catch it though, check out his answer. But nevertheless, it's a good practice to use ObservableCollections for binding.
Roel
+2  A: 

You assign the list as DataContext but the binding for ItemsSource in your listview expects a property named MyData.

Either you set the datacontext to the viewmodel and expose a MyData property containing the list or you change your ItemsSource binding to just ItemsSource="{Binding}".

EDIT: Ok, after your latest edit it still seems you have a mismatch between property name and binding. You bind to MyData but the property is called myData. (notice case difference)

Isak Savo
Sorry for my synchronous answer I wasn't copying honestly
mattythomas2000
A: 

You need to bind the ItemsSource proprety of your ListView to a property of your ViewModel

At the moment you are binding to MyData which doesn't appear to be a property of your ViewModel.

You should probably run your GetData() method in the constructor of your ViewModel, as it appears to populate a list with default data, and create a property like:

IEnumerable<MyData> MyDataList
{
    get{return myData;}
}

and set the ItemsSource of you ListView to that.

Update

You have exposed myData as a public field in MyDataViewModel. This is not the same as exposing a property. My above example is a property (now).

Also, as Roel says, you should use an ObservableCollection<MyData> rather than a List<MyData> so that you can see any changes to your collection, as they happen.

Matt Ellen
i added 2 pic to understand my problem...
Phsika
+1  A: 

As far as I can see you are assigning the list of items directly as your data context therefore your path should just be:

ItemsSource="{Binding}"

There is no property "MyData" on the list class, this is the datatype which does not need to be specified in the binding as the WPF framework will use reflection to search for all of the properties on MyData

mattythomas2000
A: 

TRY THIS

Xaml Part

<Grid>
    <StackPanel>
        <ListView Margin="8" Height="400" Width="650" ItemsSource="{Binding Path=MyData}">
            <ListView.View>
                <GridView >
                    <GridViewColumn Header="ID" Width="Auto">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding ID}" TextAlignment="Right" Width="40"/> 
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" Width="100"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Price}" Header="Price" Width="100"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Author}" Header="Author" Width="100"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Catalog}" Header="Catalog" Width="100"/>
                </GridView>
            </ListView.View>
        </ListView>
    </StackPanel>
</Grid>

View Model

public class MyDataViewModel
{
    public List<MyData> MyData { get; set; } 
    public void GetData()
    {
        MyData = new List<MyData>();
        MyData.Add(new MyData() { ID = 1, Name = "yusuf karatoprak", Author = "Mike Gold", Price = "6.7 TL", Catalog = "IT" });
        MyData.Add(new MyData() { ID = 2, Name = "yusuf karatoprak", Author = "Scott Gunitella", Price = "9.7 TL", Catalog = "IT" });
        MyData.Add(new MyData() { ID = 3, Name = "yusuf karatoprak", Author = "David Hayden", Price = "11.7 TL", Catalog = "IT" });

    }

} 

Code behind

public Window1()
    {

        InitializeComponent();

        MyDataViewModel temp = new MyDataViewModel();
        temp.GetData();
        this.DataContext = temp;


    }

Model

  public class MyData
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Price { get; set; }
    public string Author { get; set; }
    public string Catalog { get; set; }
}

this works for me

saurabh
i used below codes but result no data:(
Phsika
Can you post what you have done may be u missed something because above code should work? And you can see Output window if any Binding errors are there
saurabh
i added 2 pics to understand my problem...
Phsika
Just a little change change the case of myData to MyData
saurabh
OUTPUT: System.Windows.Data Error: 39 : BindingExpression path error: 'MyData' property not found on 'object' ''List`1' (HashCode=47422476)'. BindingExpression:Path=MyData; DataItem='List`1' (HashCode=47422476); target element is 'ListView' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
Phsika
i have edited the code above which worked for me
saurabh