Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
绑定到UserControls集合的WPF组合框不显示所选项';s文本_Wpf_Combobox_User Controls - Fatal编程技术网

绑定到UserControls集合的WPF组合框不显示所选项';s文本

绑定到UserControls集合的WPF组合框不显示所选项';s文本,wpf,combobox,user-controls,Wpf,Combobox,User Controls,我有一个组合框,它绑定到自定义UserControl的ObservableCollection。每个用户控件都有一个标记值集,组合框的DisplayMemberPath设置为“标记”。单击组合框时,这将在下拉列表中正确显示每个UserControl的标记,但是,当选择列表中的某个项目并关闭下拉列表时,组合框在按钮中不显示任何内容 如果我将UserControl替换为标准WPF控件(如TextBox),那么它将正确显示所选项的标记值,因此它与绑定到UserControl和标准WPF控件有关。另外,

我有一个组合框,它绑定到自定义UserControl的ObservableCollection。每个用户控件都有一个标记值集,组合框的DisplayMemberPath设置为“标记”。单击组合框时,这将在下拉列表中正确显示每个UserControl的标记,但是,当选择列表中的某个项目并关闭下拉列表时,组合框在按钮中不显示任何内容

如果我将UserControl替换为标准WPF控件(如TextBox),那么它将正确显示所选项的标记值,因此它与绑定到UserControl和标准WPF控件有关。另外,如果我将IsEditable设置为True,则可编辑文本框将正确显示标记,但我不希望文本可编辑

当组合框未展开时,如何显示所选项目

下面是一些复制问题的示例代码:

(注意:示例代码是从它正在运行的应用程序的上下文中提取的,因此它尝试执行的操作看起来有点奇怪,但仍然会导致相同的症状)

MyUC.xaml

<UserControl x:Class="ComboboxTest.MyUC"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBox />
    </Grid>
</UserControl>

Window1.xaml

<Window x:Class="ComboboxTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ComboboxTest"
        Title="Window1" Height="300" Width="300"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
    <StackPanel Name="ControlsHolder">
        <TextBox Tag="Box 1" Text="This is in Box 1" />
        <TextBox Tag="Box 2" Text="This is in Box 2" />
        <local:MyUC Tag="UC 1" />
        <local:MyUC Tag="UC 2" />
    </StackPanel>
    <Grid>
        <ComboBox Grid.Column="1" 
              Margin="5,0" 
              Name="MyComboBox" 
              ItemsSource="{Binding MyControls}"
              DisplayMemberPath="Tag" 
              MinWidth="120"/>
    </Grid>
</StackPanel>

Window1.cs

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace ComboboxTest
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {
        ObservableCollection<MyUC> myControls = new ObservableCollection<MyUC>();

        public Window1()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Window1_Loaded);
        }

        void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            myControls.Clear();

            foreach (UIElement uiElement in this.ControlsHolder.Children)
            {
                MyUC tb = uiElement as MyUC;

                if (tb != null)
                {
                    myControls.Add(tb);
                }
            }

            RaisePropertyChanged("MyControls");
        }

        public ObservableCollection<MyUC> MyControls
        {
            get
            {
                return this.myControls;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string p)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(p));
            }
        }
    }
}
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Windows;
使用System.Windows.Controls;
名称空间组合框测试
{
公共部分类Window1:Window,INotifyPropertyChanged
{
ObservableCollection myControl=新的ObservableCollection();
公共窗口1()
{
初始化组件();
this.Loaded+=新路由EventHandler(Window1\u已加载);
}
无效窗口1_已加载(对象发送器,路由目标e)
{
myControls.Clear();
foreach(UIElement UIElement在此.ControlsHolder.Children中)
{
MyUC tb=作为MyUC的uiElement;
如果(tb!=null)
{
myControls.Add(tb);
}
}
RaisePropertyChanged(“MyControl”);
}
公共可观察收集控制
{
得到
{
返回此.myControls;
}
}
公共事件属性更改事件处理程序属性更改;
私有void raiseProperty已更改(字符串p)
{
if(PropertyChanged!=null)
{
房地产变更(这是新的房地产变更发展(p));
}
}
}
}
此应用程序显示为:

当选择“UC 2”时,其显示为:

绑定
ui元素列表
不是一个好主意。尝试使用包装器类:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(Window1_Loaded);
        MyComboBox.ItemsSource = MyControls;
    }

    ObservableCollection<Wrapper> myControls = new ObservableCollection<Wrapper>();

    void Window1_Loaded(object sender, RoutedEventArgs e)
    {
        myControls.Clear();

        foreach (UIElement uiElement in this.ControlsHolder.Children)
        {
            MyUC tb = uiElement as MyUC;

            if (tb != null)
            {
                myControls.Add(new Wrapper(tb));
            }
        }

        RaisePropertyChanged("MyControls");
    }

    public ObservableCollection<Wrapper> MyControls
    {
        get
        {
            return this.myControls;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string p)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(p));
        }
    }
}

public class Wrapper
{
    public UserControl Control { get; protected set; }

    public Wrapper(UserControl control)
    {
        Control = control;
    }

    public Object Tag
    {
        get { return Control.Tag; }
    }
}
公共部分类窗口1:窗口
{
公共窗口1()
{
初始化组件();
this.Loaded+=新路由EventHandler(Window1\u已加载);
MyComboBox.ItemsSource=myControl;
}
ObservableCollection myControl=新的ObservableCollection();
无效窗口1_已加载(对象发送器,路由目标e)
{
myControls.Clear();
foreach(UIElement UIElement在此.ControlsHolder.Children中)
{
MyUC tb=作为MyUC的uiElement;
如果(tb!=null)
{
添加(新包装器(tb));
}
}
RaisePropertyChanged(“MyControl”);
}
公共可观察收集控制
{
得到
{
返回此.myControls;
}
}
公共事件属性更改事件处理程序属性更改;
私有void raiseProperty已更改(字符串p)
{
if(PropertyChanged!=null)
{
房地产变更(这是新的房地产变更发展(p));
}
}
}
公共类包装器
{
公共用户控件{get;protected set;}
公共包装器(用户控制)
{
控制=控制;
}
公共对象标签
{
获取{return Control.Tag;}
}
}

谢谢decyclone,它成功了。但是你有没有解释为什么将它包装在另一个类中有效,为什么绑定到UIElement是个坏主意?通过向ItemsSource添加用户控件,它们不会成为ComboBox的VisualTree的一部分。ItemsSource中的每个对象都用ComboBoxItem包装。这就是为什么它们不能很好地显示在组合框中的原因。使用ItemsSource绑定时,建议使用类而不是UIElements。我惊讶地发现有人有完全相同的问题。创建一个实用程序,以设置Prism模块(即用户控件)的Active Directory组权限。希望用户选择要为其设置权限的模块。如果他们不展示的话,那就危险了!谢谢