C# 共享可观察集合的组合框不断中断

C# 共享可观察集合的组合框不断中断,c#,wpf,combobox,C#,Wpf,Combobox,我有四个组合框正在经历一个奇怪的怪癖。我很难确切地解释到底发生了什么。。。所以我把它放在一个视频里: 代码隐藏 public ObservableCollection<ComboBoxItem> images = new ObservableCollection<ComboBoxItem>(); public ImageSelect(MainWindow mainWindow, string tab_name) { InitializeCompon

我有四个组合框正在经历一个奇怪的怪癖。我很难确切地解释到底发生了什么。。。所以我把它放在一个视频里:


代码隐藏

public ObservableCollection<ComboBoxItem> images =
    new ObservableCollection<ComboBoxItem>();

public ImageSelect(MainWindow mainWindow, string tab_name)
{
    InitializeComponent();

    Generic.ImportImages(tab_name, images1, images);

    images2.ItemsSource = images;
    images3.ItemsSource = images;
    images4.ItemsSource = images;
}
公共可观测采集图像=
新的可观察集合();
公共图像选择(主窗口主窗口,字符串选项卡\u名称)
{
初始化组件();
通用。导入图像(选项卡名称、图像1、图像);
images2.ItemsSource=图像;
images3.ItemsSource=图像;
images4.ItemsSource=图像;
}
我的班级

public static void ImportImages(string tabID, ComboBox combo, ObservableCollection<ComboBoxItem> list)
{
    try
    {
        string root = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        var files = Directory.GetFiles(Path.Combine(root, "input\\" + tabID), "*.png");

        foreach (var file in files)
        {
            string[] paths = file.Split('\\');
            ComboBoxItem item = new ComboBoxItem();
            item.Tag = paths.Last();

            var stack = new StackPanel() { Orientation = Orientation.Horizontal };
            stack.Children.Add(new Image() { Source = new BitmapImage(new Uri(file, UriKind.Absolute)), Height = 44 });
            stack.Children.Add(new Label() { Content = paths.Last(), VerticalContentAlignment = VerticalAlignment.Center });
            item.Content = stack;

            list.Add(item);
        }
    }
    catch (Exception) { }

    combo.ItemsSource = list;
}
publicstaticvoidimportimages(字符串选项卡、组合框组合、observeCollection列表)
{
尝试
{
字符串root=System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutionGassembly().Location);
var files=Directory.GetFiles(Path.Combine(root,“input\\”+tabID),“*.png”);
foreach(文件中的var文件)
{
string[]path=file.Split('\\');
ComboBoxItem=新ComboBoxItem();
item.Tag=path.Last();
var stack=new StackPanel(){Orientation=Orientation.Horizontal};
Add(new Image(){Source=new BitmapImage(new Uri(file,UriKind.Absolute)),Height=44});
添加(新标签(){Content=path.Last(),VerticalContentAlignment=VerticalAlignment.Center});
item.Content=堆栈;
列表。添加(项目);
}
}
捕获(异常){}
combo.ItemsSource=列表;
}

基本WPF示例。请看一下MVVM模式、WPF数据绑定和数据模板

视图定义

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">

<Window.Resources>

    <DataTemplate x:Key="ComboBoxItemTemplate">
        <StackPanel Orientation="Horizontal">
            <Image Height="44" Source="{Binding ImageUrl}"/>
            <Label Content="{Binding Name}" VerticalAlignment="Center"/>
        </StackPanel>
    </DataTemplate>

</Window.Resources>

<StackPanel Orientation="Horizontal">

    <ComboBox x:Name="cbOne" ItemTemplate="{StaticResource ComboBoxItemTemplate}"/>
    <ComboBox x:Name="cbTwo" ItemTemplate="{StaticResource ComboBoxItemTemplate}"/>
    <ComboBox x:Name="cbThree" ItemTemplate="{StaticResource ComboBoxItemTemplate}"/>
    <ComboBox x:Name="cbFour" ItemTemplate="{StaticResource ComboBoxItemTemplate}"/>

</StackPanel>

代码隐藏

 public partial class MainWindow : Window
{
    private ObservableCollection<ImageInfo> _images;

    public MainWindow()
    {
        InitializeComponent();

        _images = new ObservableCollection<ImageInfo>(GetImages());

        cbOne.ItemsSource = _images;
        cbTwo.ItemsSource = _images;
        cbThree.ItemsSource = _images;
        cbFour.ItemsSource = _images;
    }

    public IEnumerable<ImageInfo> GetImages()
    {
        const string path = @"C:\_D\_Log\";

        var items = from x in Directory.GetFiles(path, "*.png")
                    select new ImageInfo
                    {
                        ImageUrl = x,
                        Name = System.IO.Path.GetFileName(x)
                    };
        return items;
    }
}

public class ImageInfo
{
    public string ImageUrl { get; set; }
    public string Name { get; set; }
}
公共部分类主窗口:窗口
{
私有可观测采集图像;
公共主窗口()
{
初始化组件();
_images=新的ObservableCollection(GetImages());
cbOne.ItemsSource=\u图像;
cbTwo.ItemsSource=\u图像;
cbThree.ItemsSource=\u图像;
cbFour.ItemsSource=\u图像;
}
公共IEnumerable GetImages()
{
常量字符串路径=@“C:\\u D\\u Log\”;
var items=来自Directory.GetFiles(路径“*.png”)中的x
选择新图像信息
{
ImageUrl=x,
Name=System.IO.Path.GetFileName(x)
};
退货项目;
}
}
公共类ImageInfo
{
公共字符串ImageUrl{get;set;}
公共字符串名称{get;set;}
}

UI元素不能存在于可视树中的多个位置(或多个可视树);您不能将同一个
ComboBoxItem
添加到多个
ComboBoxItem
。那么我将如何完成我正在尝试做的事情呢?理想情况下,您应该使用对象模型来表示组合框中显示的项目(这些项目不是UI元素,因此可以共享),并设置一个
ItemTemplate
,告诉每个
组合框
如何渲染支持对象(例如,使用标签和图像)。在我离开办公室之前,我没有时间写一个合适的答案,但我想我至少可以把你推向正确的方向,或者让别人在答案上领先一步。太好了!谢谢,伙计。不过我遇到了一个问题。。。图像被“锁定”,程序运行时我无法编辑它们。我能做些什么来解决这个问题?
 public partial class MainWindow : Window
{
    private ObservableCollection<ImageInfo> _images;

    public MainWindow()
    {
        InitializeComponent();

        _images = new ObservableCollection<ImageInfo>(GetImages());

        cbOne.ItemsSource = _images;
        cbTwo.ItemsSource = _images;
        cbThree.ItemsSource = _images;
        cbFour.ItemsSource = _images;
    }

    public IEnumerable<ImageInfo> GetImages()
    {
        const string path = @"C:\_D\_Log\";

        var items = from x in Directory.GetFiles(path, "*.png")
                    select new ImageInfo
                    {
                        ImageUrl = x,
                        Name = System.IO.Path.GetFileName(x)
                    };
        return items;
    }
}

public class ImageInfo
{
    public string ImageUrl { get; set; }
    public string Name { get; set; }
}