UniformGrid和ItemsSource

4
我是一个有用的助手,可以为您翻译文本。

我有一个UniformGrid。里面,我想放置一个包含2个子元素的Grid - 一个Image和一个Canvas。我已经有一个List<Grid>成员,其中包含了这样定义的Grid

我正在将Image的源更新为实际图像,期望在UniformGrid内显示该图像,但没有任何反应。

以下是我的代码:

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");
            }
        }

编辑:添加更多代码:

    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)
        {
        }
    }
ViewModel已正确连接,其他控件的Bindings也正常工作。
我还可以看到Streams成员已正确更新,这意味着Image已使用新的Source正确更新。
我错过了什么?

你是否正在向列表中添加项目并期望它们显示出来?你是否在网格列表已经加载后更改了图像源(需要向我们展示用于绑定的代码)? - bdimag
好的,我添加了更多的代码。基本上我正在将所有的“streams”注册到一个“List”中。然后,在某个时刻,我会调用“OnNewFrameReady”函数,它应该更新“UniformGrid”。至于你的问题:是的,我正在向列表中添加项目,期望它们显示出来,第二个问题也是如此。 - Idanis
1个回答

2
也许问题在于你的项目根本没有显示出来,而不是图像没有更新(因为我看到你直接更新了图像元素的源属性)……对于列表,只有当List<>被更改时,PropertyChanged事件才会触发,而不是当某些东西被添加到列表中时,这与ObservableCollection<>不同,后者在添加/删除/替换/清除项目时触发事件。

尝试将List<>替换为ObservableCollection<>(在System.Collections.ObjectModel中找到)

除此之外,GridImage也可以在ItemsControl.ItemTemplate中定义DataTemplate,并将Source绑定到一个流ViewModel的属性上(这就是你应该拥有的集合),但与问题无关。


成功了!!! 我用 ObservableCollection 替换了 List,现在它完美地工作了。非常感谢!!! - Idanis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接