UniformGrid 和 ItemsSource
UniformGrid and ItemsSource
我有一个UniformGrid
。在里面,我想放一个 Grid
,其中包含 2 个 children - 和 Image
以及一个 Canvas
。我已经有一个 List<Grid>
成员,其中包含具有该定义的 Grid
。
我正在将 Image
的来源从 null
更新为实际图像,希望图像显示在 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
.
正确更新
我错过了什么?
可能问题是您的项目根本没有显示 -- 不是图像没有更新(因为我看到您正在更新源属性 直接图像元素)...使用列表,PropertyChanged
事件只会在 List<>
更改时触发,而不是在向其中添加内容时触发,这与 ObservableCollection<>
当项目为 added/removed/replaced/cleared.
时触发事件
尝试将 List<>
替换为 ObservableCollection<>
(在 System.Collections.ObjectModel
中找到)
除此之外,Grid
和 Image
可以在 ItemsControl.ItemTemplate
中的 DataTemplate
中定义,Source
绑定到 属性 的 stream ViewModel(这是你应该收集的)——但与问题无关。
我有一个UniformGrid
。在里面,我想放一个 Grid
,其中包含 2 个 children - 和 Image
以及一个 Canvas
。我已经有一个 List<Grid>
成员,其中包含具有该定义的 Grid
。
我正在将 Image
的来源从 null
更新为实际图像,希望图像显示在 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
.
我错过了什么?
可能问题是您的项目根本没有显示 -- 不是图像没有更新(因为我看到您正在更新源属性 直接图像元素)...使用列表,PropertyChanged
事件只会在 List<>
更改时触发,而不是在向其中添加内容时触发,这与 ObservableCollection<>
当项目为 added/removed/replaced/cleared.
尝试将 List<>
替换为 ObservableCollection<>
(在 System.Collections.ObjectModel
中找到)
除此之外,Grid
和 Image
可以在 ItemsControl.ItemTemplate
中的 DataTemplate
中定义,Source
绑定到 属性 的 stream ViewModel(这是你应该收集的)——但与问题无关。