str_str
str_str

Reputation: 103

How bind ObservableCollection to ListBox?

I have class

public class Clip
{
        public string ID { get; set; }
        public string Name { get; set; }
        public int? Duration { get; set; }
}

And ObservableCollection

public ObservableCollection<Clip> _clipsFound;
public ObservableCollection<Clip> collection
{
    get { return _clipsFound; }
    set
    {
        _clipsFound = value;
        OnPropertyChanged();
    }
}

OnPropertyChanged() is invoked when I do

_clipsFound = collection

I want binding data from collection to ListBox with three columns: ID, Name, Duration

Initialize

ID = id;
collection = new ObservableCollection<Clip>();
_clipsFound = collection;
_clipsFound.Clear();

ICollection<Clip> ClipF = await Service.GetClips(ID);
ICollection<Clip> Clipcol = ClipF;
collection = new ObservableCollection<Clip>(Clipcol);

I try do this, but it doesn't work

<ListBox Grid.Row="2"  ItemsSource="{Binding collection}" BorderBrush="Transparent" >
    <ListBox.ItemTemplate>
        <DataTemplate DataType="ui:Clip">

                <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" 
                                                           Text="{Binding Title}" 
                                                           VerticalAlignment="Center" 
                                                           HorizontalAlignment="Left"
                                                           TextTrimming="CharacterEllipsis"
                                                           Foreground="#FF4F4F4F"
                                                           FontSize="12"
                                                           Margin="55 0 0 0"/>
                <TextBlock Grid.Column="1" 
                                                           Margin="0 0 45 0"
                                                           Text="{Binding Duration}"
                                                           VerticalAlignment="Center"
                                                           HorizontalAlignment="Right"
                                                           FontSize="11"
                                                           Foreground="#FF4F4F4F"/>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>

</ListBox>

What did I do wrong?

Upvotes: 2

Views: 1104

Answers (1)

StepUp
StepUp

Reputation: 38094

You cannot send data from viewmodel to view without setting DataContext. DataContext is like channel or bridge between ViewModel and View.

This code sets DataContext:

<Window.DataContext>
   <vm:MainWindowViewModel />        
</Window.DataContext>

Let's see work example:

Your ViewModel:

public class MainWindowViewModel
{
   publicMainWindowViewModel
   {
       LoadData();
   }
   private void LoadData()
   {
      _clipsFound=new ObservableCollection<Clip>();
      for(int startIndex=0; startIndex<10; startIndex++)
      {
          collection.Add(new Clip(){ID=startIndex, Name="Bob", Duration=startIndex++});
      }
   }

   public ObservableCollection<Clip> _clipsFound;
   public ObservableCollection<Clip> collection
     {
         get
         {
             return _clipsFound;
         }
         set
         {
             _clipsFound = value;      
         }
     }
}

Your XAML:

<Window x:Class="DataGridSelectedItemsWpfApplication.MainWindow"
    ...The code omitted for the brevity...
    xmlns:vm="clr-namespace:DataGridSelectedItemsWpfApplication.ViewModel"
    Title="MainWindow" WindowStartupLocation="CenterScreen" Height="550" Width="525">
<Window.DataContext>
   <vm:MainWindowViewModel />        
</Window.DataContext>
<ListBox Grid.Row="2"  ItemsSource="{Binding collection}" BorderBrush="Transparent" >
    <ListBox.ItemTemplate>
        <DataTemplate DataType="ui:Clip">    
           <Grid>
             <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
             </Grid.ColumnDefinitions>    
             <TextBlock Text="{Binding ID}" VerticalAlignment="Center" HorizontalAlignment="Center"  FontSize="11" Margin="2" Foreground="#FF4F4F4F"/>
             <TextBlock Grid.Column="1" Margin="2" Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center"          TextTrimming="CharacterEllipsis" Foreground="#FF4F4F4F" FontSize="12"/>
             <TextBlock Grid.Column="2" Margin="2" Text="{Binding Duration}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="11" Foreground="#FF4F4F4F"/>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>    
</ListBox>
</Window>

There are many ways to set DataContext.

Upvotes: 1

Related Questions