q406157290 发表于 2015-10-13 12:23:00

c1ComboBox Template Item 问题

打开C1ComboBox 后,当前选择项的类型就显示出来了,如何解决该问题呢


KNight 发表于 2015-10-13 13:28:00

回复 1楼q406157290的帖子

需要实现ItemConverter

q406157290 发表于 2015-10-13 14:02:00

回复 2楼KNight的帖子

能稍微再详细些吗 :mj72: 谢谢您

KNight 发表于 2015-10-13 14:19:00

回复 3楼q406157290的帖子

可否把您的Demo发给我一份,方便在您的基础上实现;

q406157290 发表于 2015-10-13 14:27:00

回复 4楼KNight的帖子

demo忘记上传了 谢谢您在问题上已上传 麻烦了

KNight 发表于 2015-10-13 17:07:00

回复 5楼q406157290的帖子

你是想用C1ComboBox控件,然后下拉列表打开后同WPF自带的ComboBox相同,本身还是显示一个按钮和其Name值,是吧?


如果你想下拉张开时,本身显示Name,离开时既可显示按钮,又可显示Name,只需要实现C1ComboBox的TypeConverter即可:
public class CustomTypeConverter : TypeConverter
{
        public override object ConvertTo(ITypeDescriptorContext context,
                CultureInfo culture, object value, Type destinationType)
        {
                if (destinationType == typeof(string))
                {
                        return ((Person)value).Name;
                }
                return "";
        }
}
PointTypeBox.ItemConverter = new CustomTypeConverter();




q406157290 发表于 2015-10-13 17:24:00

回复 6楼KNight的帖子

这个在您给我提示后我自己弄出来了
抱歉刚才的提问有些变化
能否实现 选择完后 把button 和name 都同时显示出来(不离开的状态下)
最理想的状态就是选择完毕后 Tempalte中的内容全部显示在ComboBox中,如果这种没有办法实现
那就只显示Name(但是离开的时候也只要显示Name,而不要Button)
真的麻烦您了

KNight 发表于 2015-10-14 09:49:00

回复 7楼q406157290的帖子

首先先说明一下,C1ComboBox的

部分是由两个控件(EditControl 和ContentControl)叠加实现的效果,而这两个控件之间的切换效果更新方法如下:
protected internal void UpdateVisualState()
{
        if (this.EditControl == null || this.ContentControl == null)
        {
                return;
        }
        if (this.IsInEditMode || this.IsDropDownOpen)
        {
                this.EditControl.Opacity = 1.0;
                this.EditControl.IsTabStop = true;
                this.EditControl.IsHitTestVisible = true;
                this.ContentControl.Visibility = Visibility.Collapsed;
                this.ContentControl.Content = null;
        }
        else
        {
                this.EditControl.Opacity = 1.4012984643248171E-45;
                this.EditControl.IsTabStop = false;
                this.EditControl.IsHitTestVisible = false;
                this.ContentControl.Visibility = Visibility.Visible;
                this.ContentControl.Content = this.ActualContent;
        }
        base.Cursor = (this.IsEditable ? Cursors.IBeam : Cursors.Arrow);
}
// 注:C1ComboBox->C1EditableContentControl->EditControl/ContentControl
所以只要保证你下拉选择完成后 this.IsInEditMode || this.IsDropDownOpen 的值为false即可,故添加如下代码:
Loaded += (sender, e) =>
{
        _editBox = GetChildObjects<C1TextEditableContentControl>(PointTypeBox,
                typeof(C1TextEditableContentControl));
        PointTypeBox.IsDropDownOpenChanged += (sender2, e2) =>
        {
                _editBox.IsInEditMode = false;
        };
};
其中GetChildObjects方法为获取子控件的方法:
public List<T> GetChildObjects<T>(DependencyObject obj, Type typename) where T : FrameworkElement
{
        DependencyObject child = null;
        List<T> childList = new List<T>();

        for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
        {
                child = VisualTreeHelper.GetChild(obj, i);

                if (child is T &amp;&amp; (((T)child).GetType() == typename))
                {
                        childList.Add((T)child);
                }
                childList.AddRange(GetChildObjects<T>(child, typename));
        }
        return childList;
}

这样可以保证你下拉选择完成后,即可将DataTemplate的内容完全显示在图中的位置;但是当鼠标在其上获取焦点时,仍旧是会变成字符串,即显示其中EditControl控件的;

q406157290 发表于 2015-10-14 10:33:00

回复 8楼KNight的帖子

厉害真的太厉害了 谢谢您
下拉选择完成后,即可将DataTemplate的内容完全显示在图中的位置
但是当鼠标在其上获取焦点时,能否不变成字符串,还是该DataTemplate控件,并且DataTemplate中的Button可以点击

KNight 发表于 2015-10-14 12:03:00

回复 9楼q406157290的帖子

有一种解决方案是:
展开下拉菜单时,最上面那里显示字符串(Name),而不是显示完整的DataTemplate控件,但是可以保证当焦点在C1ComboBox时会显示完整的DataTemplate控件的;此时只需要在上面的代码基础上加上:
_editBox.IsEditable = false;
_editBox.GotFocus += (sender2, e2) =>
{
        _editBox.IsInEditMode = false;
        _editBox.IsTabStop = true;
};

PointTypeBox.IsDropDownOpenChanged += (sender2, e2) =>
{
        _editBox.IsInEditMode = false;// 貌似无效
};
如果先要显示的字符串为Name字段,则需要加上之前说的ItemConverter;

还有一种就是要实现和WPF自带的ComboBox完全一样的效果,这个比较麻烦一些,因为C1ComboBox在展开下拉框时,IsDropDownOpen属性为true,而且它会自动调用其中一个UpdateSwappedOut()方法,修改_editBox的ActualContent属性,以触发UpdateVisualState()来调换EditControl和EditControl两个控件;但是UpdateSwappedOut()的方法触发,以及其中对ActualContent属性的修改触发UpdateVisualState(),我都没有找到可在外面控制的;所以,狠狠心,就把UpdateSwappedOut()给整出来,然后自己控制这两个控件的调换:
首先声明两个全局控件变量:
Control EditControl;
ContentPresenter ContentControl;

其次在加载完成后通过GetChildObjects获取该两个控件:
EditControl = GetChildObjects<Control>(PointTypeBox, "EditControl");
ContentControl = GetChildObjects<ContentPresenter>(PointTypeBox, "ContentControl");
_editBox = GetChildObjects<C1TextEditableContentControl>(PointTypeBox,
        typeof(C1TextEditableContentControl));
_editBox.IsEditable = false;
// 保证在触发C1ComboBox焦点时,不会变成编辑控件
_editBox.GotFocus += (sender2, e2) =>
{
        _editBox.IsInEditMode = false;
        _editBox.IsTabStop = true;
};

PointTypeBox.IsDropDownOpenChanged += (sender2, e2) =>
{
        UpdateVisualState();
};

private void UpdateVisualState()
{
        if (this.EditControl == null || this.ContentControl == null)
        {
                return;
        }
        this.EditControl.Opacity = 1.4012984643248171E-45;
        this.EditControl.IsTabStop = false;
        this.EditControl.IsHitTestVisible = false;
        this.ContentControl.Visibility = Visibility.Visible;
        C1ComboBoxItem cmbi = ((C1ComboBoxItem)PointTypeBox.ItemContainerGenerator.ContainerFromIndex(PointTypeBox.SelectedIndex));
        this.ContentControl.Content = cmbi.Content;
        base.Cursor = (_editBox.IsEditable ? Cursors.IBeam : Cursors.Arrow);
}

算是给了个下下策的解决方案了...希望能用上!
页: [1] 2
查看完整版本: c1ComboBox Template Item 问题