C# 带有组合框的CustomControl
使用组合框创建自定义控件时遇到问题 这是我的简单代码:C# 带有组合框的CustomControl,c#,.net,wpf,combobox,custom-controls,C#,.net,Wpf,Combobox,Custom Controls,使用组合框创建自定义控件时遇到问题 这是我的简单代码: public class MyComboBox : Control { public IEnumerable ItemsSource { get { return (IEnumerable)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } // Using a De
public class MyComboBox : Control
{
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(MyComboBox), new UIPropertyMetadata(null));
public string DisplayMemberPath
{
get { return (string)GetValue(DisplayMemberPathProperty); }
set { SetValue(DisplayMemberPathProperty, value); }
}
// Using a DependencyProperty as the backing store for DisplayMemberPath. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DisplayMemberPathProperty =
DependencyProperty.Register("DisplayMemberPath", typeof(string), typeof(MyComboBox), new UIPropertyMetadata(""));
public string SelectedValuePath
{
get { return (string)GetValue(SelectedValuePathProperty); }
set { SetValue(SelectedValuePathProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedValuePath. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedValuePathProperty =
DependencyProperty.Register("SelectedValuePath", typeof(string), typeof(MyComboBox), new UIPropertyMetadata(""));
public object SelectedValue
{
get { return (object)GetValue(SelectedValueProperty); }
set { SetValue(SelectedValueProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedValueProperty =
DependencyProperty.Register("SelectedValue", typeof(object), typeof(MyComboBox), new UIPropertyMetadata(null));
public int SelectedIndex
{
get { return (int)GetValue(SelectedIndexProperty); }
set { SetValue(SelectedIndexProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedIndex. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedIndexProperty =
DependencyProperty.Register("SelectedIndex", typeof(int), typeof(MyComboBox), new UIPropertyMetadata(0));
static MyComboBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyComboBox), new FrameworkPropertyMetadata(typeof(MyComboBox)));
}
}
这是它的Generic.xaml:
<Style TargetType="{x:Type local:MyComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyComboBox}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="MyComboBox" />
<ComboBox Grid.Column="1"
ItemsSource="{Binding Path=ItemsSource, RelativeSource={RelativeSource Mode=TemplatedParent}}"
SelectedIndex="{Binding Path=SelectedIndex, RelativeSource={RelativeSource Mode=TemplatedParent}}"
DisplayMemberPath="{Binding Path=DisplayMemberPath, RelativeSource={RelativeSource Mode=TemplatedParent}}"
SelectedValuePath="{Binding Path=SelectedValuePath, RelativeSource={RelativeSource Mode=TemplatedParent}}"
SelectedValue="{Binding Path=SelectedValue, RelativeSource={RelativeSource Mode=TemplatedParent}}">
</ComboBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
当我从Generic.xaml中删除属性SelectedIndex时,问题就消失了,但我需要它,因为我希望使用我的控件的人可以拥有与组合框相同的基本功能。有人知道怎么解决吗?起初,我觉得你的问题在SelectedValue中。在您的VM中,它的类型是int,但WPF希望它是KeyValuePair。集合项的类型
ItemsSource="{Binding Path=MyNumbers}" // KeyValuePair
DisplayMemberPath="Key"
SelectedValuePath="Value"
SelectedValue="{Binding Path=MyNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" // int
然后我意识到我的错误,SelectedItem必须是KeyValuePair类型。
错误消息看起来是WPF没有查看SelectedValuePath提供的items属性,而是试图将其显式转换为KeyValue对。这不是记录在案的行为。我自己找到了解决方案。
问题出在我为SelectedIndex插入的默认值上:它必须是-1而不是0。您有没有理由从头开始创建一个组合框,而不扩展/使用现有的组合框?这只是我想要构建的自定义控件的一部分。我只取不起作用的部分。而且,如果你从MyComboBox中选择一个值,一切都开始正常工作。那么问题就出在VS的设计器上了?在运行时一切正常?不,问题在于启动应用程序时。在有人更改组合框值之前,红色边框是可见的。
public class ViewModel : INotifyPropertyChanged
{
private int _number;
public int Number
{
get { return _number; }
set
{
_number = value;
OnPropertyChanged("Number");
}
}
public Dictionary<string, int> Numbers { get; set; }
private int _myNumber;
public int MyNumber
{
get { return _myNumber; }
set
{
_myNumber = value;
OnPropertyChanged("MyNumber");
}
}
public Dictionary<string, int> MyNumbers { get; set; }
public ViewModel()
{
Numbers = new Dictionary<string, int>()
{
{ "One", 1 },
{ "Two", 2 },
{ "Three", 3 }
};
Number = 1;
MyNumbers = new Dictionary<string, int>()
{
{ "Four", 4 },
{ "Five", 5 },
{ "Six", 6 }
};
MyNumber = 4;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChangedEventHandler e = PropertyChanged;
if (e != null)
{
e(this, new PropertyChangedEventArgs(name));
}
}
}
System.Windows.Data Error: 23 : Cannot convert '[Four, 4]' from type 'KeyValuePair`2' to type 'System.Int32' for 'en-US' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: Int32Converter cannot convert from System.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].
at System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
at System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)'
System.Windows.Data Error: 7 : ConvertBack cannot convert value '[Four, 4]' (type 'KeyValuePair`2'). BindingExpression:Path=MyNumber; DataItem='ViewModel' (HashCode=55591935); target element is 'MyComboBox' (Name=''); target property is 'SelectedValue' (type 'Object') NotSupportedException:'System.NotSupportedException: Int32Converter cannot convert from System.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].
at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)
at MS.Internal.Data.ObjectTargetConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
at System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'
ItemsSource="{Binding Path=MyNumbers}" // KeyValuePair
DisplayMemberPath="Key"
SelectedValuePath="Value"
SelectedValue="{Binding Path=MyNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" // int