将图像控件绑定到可观察集合

发布于 2024-12-28 06:38:40 字数 4528 浏览 1 评论 0原文

我试图获取 BitmapSource 对象的 ObservableCollection 来绑定到我的 WPF 表单上的一堆图像,但图像从未显示...我验证了图像正在加载到属性中,但我的绑定一定不正确... .绑定路径应该如何编码?我曾经将每个图像绑定到一堆不同的对象,但是使用列表要好得多,所以我想以这种方式绑定它们......

文本框正确显示 ProgramPath 属性,我只是不能获取绑定 XAML 的图像源

- 在网格内我有许多彼此相邻的文本框和图像

<TextBox HorizontalAlignment="Stretch" Margin="24,2,2,2" Name="TextBoxA" VerticalAlignment="Stretch" 
                          Width="664" >
                    <Binding Path=".[0].ProgramPath" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:ExternalProgramValidator/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox>
                <TextBox Grid.Row="1" HorizontalAlignment="Stretch" Margin="24,2,2,2" Name="TextBoxB" VerticalAlignment="Stretch" Width="664" >
                    <Binding Path=".[1].ProgramPath" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:ExternalProgramValidator/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox>

<Image Height="16   " HorizontalAlignment="Left" 
                       Margin="4" Name="ImageA" Stretch="Fill" VerticalAlignment="Center" Width="16"                           
                       Source="{Binding Path=.[0].ProgramImage, UpdateSourceTrigger=PropertyChanged}">
                </Image>
                <Image Grid.Row="1" Height="16   " HorizontalAlignment="Left" 
                       Margin="4" Name="ImageB" Stretch="Fill" VerticalAlignment="Center" Width="16"
                       Source="{Binding Path=.[0].ProgramImage, UpdateSourceTrigger=PropertyChanged}"/>

然后我有一个像这样的公共类

public class ExternalProgramsWindowData : INotifyPropertyChanged
{
    private BitmapSource _ExtractPathImage(string fullPath)
    {
        BitmapSource returnedImage = null;

        string pathForImage = string.Empty;
        string[] s = fullPath.Split(new string[] { ".exe" }, StringSplitOptions.None);

        if (s[0] != null)
        {
            pathForImage = s[0] + ".exe";
        }

        if (!string.IsNullOrWhiteSpace(pathForImage))
        {
            System.Drawing.Icon icon = IconExtractor.GetIcon(pathForImage, true);

            returnedImage = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                icon.Handle,
               System.Windows.Int32Rect.Empty,
                System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
        }

        return returnedImage;

    }

    /// <summary>
    /// A
    /// </summary>
    private string _programPath;
    public string ProgramPath
    {
        get { return _programPath; }
        set
        {
            _programPath = value;
            Notify("ProgramPath");
            ProgramImage = _ExtractPathImage(_programPath);
        }
    }

    private BitmapSource _programImage;
    public BitmapSource ProgramImage
    {
        get { return _programImage; }
        set
        {
            _programImage = value;
            Notify("ProgramImage");
        }
    }


    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void Notify(string propName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

    #endregion
}

在主窗口类中我将网格绑定到这些类对象的集合

/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class ExternalProgramsWindow : Window
{


    public ObservableCollection<ExternalProgramsWindowData> WindowDataList { get; set; }


WindowDataList = new ObservableCollection<ExternalProgramsWindowData>();

        ExternalPrograms_ExternalProgramsGrid.DataContext = WindowDataList;

然后我加载集合和 ProgramPath 属性已设置,并且它会触发设置ProgramImage(正确设置为图像,但窗口不显示图像)

foreach (ExternalProgram program in externalProgramList)
        {
            ExternalProgramsWindowData oExternalProgramsWindowData = new ExternalProgramsWindowData();
            oExternalProgramsWindowData.ProgramPath = program.Path + " " + program.Arguments;


            WindowDataList.Add(oExternalProgramsWindowData);

I am trying to get an ObservableCollection of BitmapSource objects to bind to a bunch of Images on my WPF form and the image never shows...I verified the image is being loaded into the property, but my binding must be incorrect.....how should the binding path be coded? I used to have each image bound to a bunch of different objects, but a list is a lot better to use so I want to bind them that way......

The textboxes display the ProgramPath property correctly, I just can't get the image sources bound

XAML - Inside a Grid I have a number of textboxes and images next to each other

<TextBox HorizontalAlignment="Stretch" Margin="24,2,2,2" Name="TextBoxA" VerticalAlignment="Stretch" 
                          Width="664" >
                    <Binding Path=".[0].ProgramPath" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:ExternalProgramValidator/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox>
                <TextBox Grid.Row="1" HorizontalAlignment="Stretch" Margin="24,2,2,2" Name="TextBoxB" VerticalAlignment="Stretch" Width="664" >
                    <Binding Path=".[1].ProgramPath" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <local:ExternalProgramValidator/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox>

<Image Height="16   " HorizontalAlignment="Left" 
                       Margin="4" Name="ImageA" Stretch="Fill" VerticalAlignment="Center" Width="16"                           
                       Source="{Binding Path=.[0].ProgramImage, UpdateSourceTrigger=PropertyChanged}">
                </Image>
                <Image Grid.Row="1" Height="16   " HorizontalAlignment="Left" 
                       Margin="4" Name="ImageB" Stretch="Fill" VerticalAlignment="Center" Width="16"
                       Source="{Binding Path=.[0].ProgramImage, UpdateSourceTrigger=PropertyChanged}"/>

Then I have a public class like this

public class ExternalProgramsWindowData : INotifyPropertyChanged
{
    private BitmapSource _ExtractPathImage(string fullPath)
    {
        BitmapSource returnedImage = null;

        string pathForImage = string.Empty;
        string[] s = fullPath.Split(new string[] { ".exe" }, StringSplitOptions.None);

        if (s[0] != null)
        {
            pathForImage = s[0] + ".exe";
        }

        if (!string.IsNullOrWhiteSpace(pathForImage))
        {
            System.Drawing.Icon icon = IconExtractor.GetIcon(pathForImage, true);

            returnedImage = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                icon.Handle,
               System.Windows.Int32Rect.Empty,
                System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
        }

        return returnedImage;

    }

    /// <summary>
    /// A
    /// </summary>
    private string _programPath;
    public string ProgramPath
    {
        get { return _programPath; }
        set
        {
            _programPath = value;
            Notify("ProgramPath");
            ProgramImage = _ExtractPathImage(_programPath);
        }
    }

    private BitmapSource _programImage;
    public BitmapSource ProgramImage
    {
        get { return _programImage; }
        set
        {
            _programImage = value;
            Notify("ProgramImage");
        }
    }


    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void Notify(string propName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

    #endregion
}

In the Main window class I bind the grid to a collection of those class objects

/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class ExternalProgramsWindow : Window
{


    public ObservableCollection<ExternalProgramsWindowData> WindowDataList { get; set; }


WindowDataList = new ObservableCollection<ExternalProgramsWindowData>();

        ExternalPrograms_ExternalProgramsGrid.DataContext = WindowDataList;

Then I load the collection and and the ProgramPath property is set and it triggers setting the ProgramImage (which gets set to an image correctly, but the window does not display the image)

foreach (ExternalProgram program in externalProgramList)
        {
            ExternalProgramsWindowData oExternalProgramsWindowData = new ExternalProgramsWindowData();
            oExternalProgramsWindowData.ProgramPath = program.Path + " " + program.Arguments;


            WindowDataList.Add(oExternalProgramsWindowData);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丘比特射中我 2025-01-04 06:38:40

尝试通过继承自定义类作为 ObservableCollection 来使用它。在上面的代码中,我看不到可观察集合和要绑定到的属性之间的链接。

// assuming ExternalProgramsWindowData are your bitmap objects
public class SourceList : ObservableCollection<ExternalProgramsWindowData> {

}

public class ViewModel : INotifyPropertyChanged {

    private SourceList mySourceList;

    public SourceList MySourceList {
         get { return mySourceList; }
         set {
             mySourceList = value;
             FirePropertyChanged("MySourceList");
             }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void FirePropertyChanged (string propertyName) {

        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

那么在实际的Binding中你会遇到以下情况:

Binding的来源:ViewModel对象。
绑定路径:“MySourceList”。

我不熟悉ExternalProgramsWindowData 数据,但也许您必须使用ValueConverter 才能使绑定工作。

因此请注意,当您的视图模型数据与视图数据不兼容时,尽管绑定路径设置正确,但绑定将不起作用。

希望这有帮助:)

Try to use a custom class as an ObservableCollection through inheriting from it. In your code above I can't see the link between the oberservable collection and the property you want to bind to.

// assuming ExternalProgramsWindowData are your bitmap objects
public class SourceList : ObservableCollection<ExternalProgramsWindowData> {

}

public class ViewModel : INotifyPropertyChanged {

    private SourceList mySourceList;

    public SourceList MySourceList {
         get { return mySourceList; }
         set {
             mySourceList = value;
             FirePropertyChanged("MySourceList");
             }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void FirePropertyChanged (string propertyName) {

        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

Then in the actual Binding you have the following situation:

Source of the Binding: The object ViewModel.
Path of the Binding: "MySourceList".

I am not familiar with ExternalProgramsWindowData data but maybe you have to use a ValueConverter in order to make the binding work.

So note that when your viewmodels data is not compatible to your Views data the binding would not work although the binding paths are set correctly.

Hope this helps :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文