4

I have a UniformGrid. Inside, I would like to put a Grid which contains 2 children - and Image and a Canvas. I already have a List<Grid> member which contains a Grid with that definition.

I'm updating the source of the Image from null to an actual image, expecting the image to be shown inside the UniformGrid, but nothing happens.

Here's my code:

Xaml:

<Border Grid.Row="0" >
        <ItemsControl x:Name="StreamsItemsControl" ItemsSource="{Binding Streams}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid x:Name="StreamsGrid"  ClipToBounds="True" Height="300" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Border>

ViewModel:

private List<Grid> m_streams = new List<Grid>();
public List<Grid> Streams
        {
            get { return m_streams; }
            set
            {
                m_streams = value;
                OnPropertyChanged("Streams");
            }
        }

Edit: Adding more code:

    public struct StreamContainer
    {
        public string StreamName;
        public Grid StreamGrid;
        public Canvas StreamCanvas;
        public Image StreamImage;
    }
    private readonly List<StreamContainer> m_streamsContainer = new List<StreamContainer>();

    public SequencesPlayerViewModel()
    {
        RegisterStream("Color");
        RegisterStream("Depth");
        RegisterStream("Ir");
        RegisterStream("Left");
    }

    private void RegisterStream(string streamName)
    {
        StreamContainer streamContainer;

        streamContainer.StreamName = streamName;
        streamContainer.StreamCanvas = new Canvas { Name = streamName + "Canvas", Background = Brushes.Transparent, VerticalAlignment = VerticalAlignment.Top };
        streamContainer.StreamImage = new Image { Name = streamName + "Image", Stretch = Stretch.Uniform, VerticalAlignment = VerticalAlignment.Top };

        var widthBinding = new Binding { Path = new PropertyPath("ActualWidth") };
        var heightBinding = new Binding
        {
            Path = new PropertyPath("ActualHeight"),
            Source = streamContainer.StreamImage
        };


        streamContainer.StreamCanvas.SetBinding(FrameworkElement.HeightProperty, heightBinding);
        streamContainer.StreamCanvas.SetBinding(FrameworkElement.WidthProperty, widthBinding);

        streamContainer.StreamGrid = new Grid { Name = streamName + "Grid" };
        streamContainer.StreamGrid.Children.Add(streamContainer.StreamImage);
        streamContainer.StreamGrid.Children.Add(streamContainer.StreamCanvas);

        streamContainer.StreamGrid.Visibility = Visibility.Collapsed;

        m_streamsContainer.Add(streamContainer);
    }

    private void AddStream(StreamContainer currentStream)
    {
        var listOfStreams = GetListOfStream();

        if (listOfStreams.Count > 0)
        {
            var streamToAdd = listOfStreams.Find(currStream => currStream.Name == currentStream.StreamName);
            if (streamToAdd != null)
                if (!String.IsNullOrEmpty(currentStream.StreamName))
                {
                    currentStream.StreamGrid.Visibility = Visibility.Visible;
                    (currentStream.StreamGrid.Children[0] as Image).Source = streamToAdd.ImageBitmap;
                }
        }

        Streams.Add(currentStream.StreamGrid);
    }

    private void OnNewFrameReady(uint frameNumber)
    {
        try
        {
            var listOfStreams = GetListOfStream();

            foreach (var elem in Streams)
            {
                var currentCanvas = (elem.Children[1] as Canvas);
                var canvasName = currentCanvas.Name.Split(new[] { "Canvas" }, StringSplitOptions.RemoveEmptyEntries).First();

                var currentStream = listOfStreams.Find(currStream => currStream.Name == canvasName);
                if (!String.IsNullOrEmpty(currentStream.Name))
                    (elem.Children[0] as Image).Source = currentStream.ImageBitmap;
                Panel p = currentCanvas;
                elem.UpdateLayout();

                elem.Width = (elem.Children[0] as Image).ActualWidth;
                elem.Height = (elem.Children[0] as Image).ActualHeight;
                elem.UpdateLayout();
            }
        }
        catch (Exception ex)
        {
        }
    }

The ViewModel is connected correctly, and the Bindings of the other controls are working properly.

I can also see that the Streams member is updated correctly, meaning that the Image was correctly updated with the new Source.

What am I missing?

Idanis
  • 1,918
  • 6
  • 38
  • 69
  • Are you adding items to the list and expecting them to show up? Are you changing the image source after the list of grids has already been loaded (need to show us the code used for binding that)? – bdimag Jun 18 '15 at 20:21
  • Ok, I added more code. Basically I'm registering all `streams` to a `List`. Then, at some point, I'm calling the `OnNewFrameReady` function, which should update the `UniformGrid`. As for your questions: Yes, I'm adding items to the list, expecting them to show up, and Yes for the second question as well. – Idanis Jun 18 '15 at 20:34

1 Answers1

2

Perhaps the issue is that your items are not showing up at all -- not that the image isn't updating (because I see you're updating the source property of the image element directly)... With a list, the PropertyChanged event will only fire when the List<> is changed, not when something is added to it, unlike the ObservableCollection<> which fires events when items are added/removed/replaced/cleared.

Try replacing your List<> with an ObservableCollection<> (found in System.Collections.ObjectModel)

Other than that, the Grid and Image could instead be defined in a DataTemplate within the ItemsControl.ItemTemplate and the Source bound to a property of a stream ViewModel (which is what you should have a collection of) -- but unrelated to the issue.

bdimag
  • 953
  • 8
  • 11
  • Worked!!! I replaced the `List` with `ObservableCollection` and it works like a charm. Thanks a lot!!! – Idanis Jun 18 '15 at 21:08