【问题标题】:Update WPF Images from a list从列表中更新 WPF 图像
【发布时间】:2016-03-12 15:56:10
【问题描述】:

我在一个窗口中有 40 张图像需要更改。我认为检查这 40 个图像是否需要在计时器上更改的最简单方法是将它们放入 List<ImgInfo>,其中 ImgInfo 包含 System.Windows.Controls.Image

我的代码更新了列表,但不会更改窗口上的当前图像。

我对在 WPF 中处理图像非常陌生。 我应该将这些图像绑定到代码中的属性吗?现在 xaml 只是将源设置为单个图像。将这些图像绑定到列表中的项目需要什么?

// xaml:
 <Image x:Name="comp01" Height="75" Source="img/comp-offline.png" Stretch="Fill" Margin="5"/>

// When the application starts:
ImgInfoList= new List<ImgInfo>();
ImgInfoList.Add(new ImgInfo{ CurrentImage = comp01, MachineName = "" });
ImgInfoList.Add(new ImgInfo{ CurrentImage = comp02, MachineName = "" });
// ... etc for 40 images

// ImgInfo class:
public class ImgInfo
{
    public string MachineName { get; set; }
    public Image CurrentImage { get; set; }
}

public void MainTimer_Tick(object sender, EventArgs e)
{
    foreach(var imgInfo in ImageInfoList)
    {
        if(//conditions are true) 
        {
            Image imgTmp = new Image();
            BitmapImage bi3 = new BitmapImage();
            bi3.BeginInit();
            bi3.UriSource = new Uri(LoadBitmapURIFromResource("img/img-1.png"));
            bi3.EndInit();
            imgTmp.Stretch = Stretch.Fill;
            imgTmp.Source = bi3;
            imgInfo.CurrentImage = imgTmp;
        }
        // else if... img/img-2.png, etc.
    }
}

//LoadBitmapURIFromResource just returns Convert.ToString(new Uri(@"pack://application:,,,/" + assembly.GetName().Name + ";component/" + pathInApplication, UriKind.Absolute));

【问题讨论】:

    标签: c# .net wpf binding


    【解决方案1】:

    要在 WPF 中处理多个图像,您应该对图像使用 ObservableCollection(仅包含文件名)并将其用作 ListBox 的 ItemsSource。 ItemTemplate 将是您的图像,它绑定到文件名。

        <ListBox ItemsSource="{Binding ImgList}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding}" ... />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    

    ImgList 必须是 DataContext 中的一个属性。 如果您需要不同的 ListBox 布局,您可以更改 ListBox 的 ItemsPanel。

    要更改图像,只需替换字符串。请注意,默认情况下图像组件会缓存图像。如果你想从同一个文件重新加载图像,你必须禁用缓存。

    编辑:

    正如所承诺的,我想展示如何使用绑定在&lt;Canvas/&gt; 的特定位置显示图像。首先,我们需要修改你的ImgInfo 类。它现在包含要显示的图像的路径、位置和大小:

    public class ImgInfo
    {
        public string Path { get; set; }
        public double X { get; set; }
        public double Y { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
    }
    

    &lt;ListBox/&gt; 将通过以下方式扩展:

        <ListBox ItemsSource="{Binding ImgList}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding Path}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
                    <Setter Property="Canvas.Left" Value="{Binding X}"/>
                    <Setter Property="Canvas.Top" Value="{Binding Y}"/>
                    <Setter Property="Width" Value="{Binding Width}"/>
                    <Setter Property="Height" Value="{Binding Height}"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    

    作为ItemsPanel,我们使用&lt;Canvas/&gt;-元素。为了确保项目显示在特定位置,我们修改 ItemContainerStyle 以将相应的属性绑定到我们的 ImgInfo 实例。

    现在您可以在ImgList 中添加新项目或替换它们,更改将反映在&lt;ListBox/&gt; 中。如果要直接修改ImgInfo-Items,则必须在该类中实现INotifyPropertyChanged

    【讨论】:

    • 我必须使用列表框吗?这些图像具有非常特殊的排列方式,例如平面图。
    • 您不必这样做 - 但它使处理变得更加容易。如果你想要一个特殊的对齐方式,你可以使用 Canvas 作为 ItemsPanel。还是布局总是一样的?
    • 我更喜欢更通用的处理方式,例如列表框,因为它将用于 3 种不同(但不变)的排列,但由于它是房间布局,这可能非常困难。目前我正在使用画布。自从您回答以来,我一直在阅读有关 ObservableCollection 的大量内容,今天我将尝试一下。
    • 当我在家时,我将扩展我的答案如何使用带有画布的列表框。 (我有一个想法,但我必须先尝试一下)
    • 仍然没有可行的解决方案,但这帮助我走上了使用带有 ObservableCollection 的 ListBox 的正确道路。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    相关资源
    最近更新 更多