C# WPF Customcontrol、模板、继承和从属属性
我需要创建的自定义控件遇到一些问题。我试着先向你解释我的需要 我需要一个允许一次检查多个项目的组合框(使用复选框),但我希望它足够智能,能够绑定到特定类型 我找到了一些MultiSelectionComboBox,但没有一个能反映我的需要。 顺便说一句,我的主要问题是我希望有一个泛型类C# WPF Customcontrol、模板、继承和从属属性,c#,wpf,xaml,C#,Wpf,Xaml,我需要创建的自定义控件遇到一些问题。我试着先向你解释我的需要 我需要一个允许一次检查多个项目的组合框(使用复选框),但我希望它足够智能,能够绑定到特定类型 我找到了一些MultiSelectionComboBox,但没有一个能反映我的需要。 顺便说一句,我的主要问题是我希望有一个泛型类 public class BaseClass<T> : BaseClass { public static readonly DependencyProperty ItemsSourcePro
public class BaseClass<T> : BaseClass
{
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable<T>), typeof(BaseClass<T>), new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(BaseClass<T>.OnItemsSourceChanged)));
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
int i = 0;
//MultiSelectComboBox control = (MultiSelectComboBox)d;
//control.DisplayInControl();
}
public IEnumerable<T> ItemsSource
{
get { return (IEnumerable<T>)GetValue(ItemsSourceProperty); }
set
{
SetValue(ItemsSourceProperty, value);
}
}
}
public class BaseClass : Control
{
}
公共类基类:基类
{
公共静态只读依赖项Property ItemsSourceProperty=
DependencyProperty.Register(“ItemsSource”、typeof(IEnumerable)、typeof(BaseClass)、new FrameworkPropertyMetadata(null、,
新属性ChangedCallback(BaseClass.OnItemSourceChanged));
私有静态资源已更改(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
int i=0;
//MultiSelectComboBox控件=(MultiSelectComboBox)d;
//控件。显示InControl();
}
公共IEnumerable ItemsSource
{
get{return(IEnumerable)GetValue(ItemsSourceProperty);}
设置
{
设置值(ItemsSourceProperty,value);
}
}
}
公共类基类:控件
{
}
还有一个更特定于上下文的项目,例如
public class MultiCurr : BaseClass<Currency>
{
static MultiCurr()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiCurr), new FrameworkPropertyMetadata(typeof(MultiCurr)));
}
}
公共类多币种:基类
{
静态多curr()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiCurr)),new FrameworkPropertyMetadata(typeof(MultiCurr));
}
}
在我的App.xaml中,我将资源定义为
<ResourceDictionary>
<Style TargetType="local:MultiCurr">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MultiCurr">
<ComboBox Width="120" Background="Red" Height="30" ItemsSource="{Binding ItemsSource}" DisplayMemberPath="Description" ></ComboBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
在我的主窗口中,我创建了一个对象作为
<Grid>
<local:MultiCurr x:Name="test" ItemsSource="{Binding Currencies}"></local:MultiCurr>
</Grid>
并且MainWindow.cs定义为
公共部分类主窗口:窗口,INotifyPropertyChanged
{
私人货币
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var lst = new List<Currency>();
for (int i = 0; i < 10; i++)
{
var curr = new Currency
{
ID = i,
Description = string.Format("Currency_{0}", i)
};
lst.Add(curr);
}
Currencies = lst;
}
public IList<Currency> Currencies
{
get
{
return this.currencies;
}
set
{
this.currencies = value;
NotifyPropertyChanged("Currencies");
}
}
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public主窗口()
{
初始化组件();
this.DataContext=this;
this.Loaded+=主窗口\u Loaded;
}
已加载无效主窗口(对象发送器、路由目标)
{
var lst=新列表();
对于(int i=0;i<10;i++)
{
var curr=新货币
{
ID=i,
Description=string.Format(“货币{0}”,i)
};
第一次添加(当前);
}
货币=lst;
}
公共货币
{
得到
{
返回此文件。请选择其他货币;
}
设置
{
货币=价值;
通知财产变更(“货币”);
}
}
公共事件属性更改事件处理程序属性更改;
//此方法由每个属性的集合访问器调用。
//应用于可选propertyName的CallerMemberName属性
//参数导致调用方的属性名被替换为参数。
私有void NotifyPropertyChanged(字符串propertyName=“”)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
这是结果。。。
我想知道我做错了什么?有没有可能我想要达到什么目的
谢谢
更新#1:
我已经看到,主要问题是定制usercontrol的datacontext
<Application.Resources>
<ResourceDictionary>
<Style TargetType="local:MultiCurr">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MultiCurr">
<ComboBox Width="120" Background="Red" Height="30" ItemsSource="{Binding **Currencies**}" DisplayMemberPath="{Binding **DisplayMemeberPath**}" ></ComboBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
如果有人想尝试解决方案
谢谢
Combobox不适合用于multiselection的控件,因为它提供了一种行为,即当您选择项时,Combobox会自动关闭。这就是为什么Combobox没有像ListBox那样的SelectionMode属性。我认为扩展器中的列表框是您所需要的
泛型类型不是一条出路。WPF以不同、更好的方式处理此问题。以listbox为例。如果您将listbox.itemssource绑定到泛型observable集合,并尝试定义例如ItemTemplate,则在编写绑定时会获得完整的intellisense,如果绑定到不存在的属性,则会发出警告。WPF设计器自动识别可观察集合的类型参数。当然,您需要在页面中指定datacontext的类型,方法如下:d:datacontext=“{d:DesignInstance search:AdvancedSearchPageViewModel}”
。但是,您的控件不必是,并且不应该知道项目的类型
以下示例演示了满足您的要求的控件:
<Expander>
<Expander.Header>
<ItemsControl ItemsSource="{Binding ElementName=PART_ListBox, Path=SelectedItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding Mode=OneWay}" />
<Run Text=";" />
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Expander.Header>
<Expander.Content>
<ListBox x:Name="PART_ListBox" SelectionMode="Multiple">
<ListBox.ItemsSource>
<x:Array Type="system:String">
<system:String>ABC</system:String>
<system:String>DEF</system:String>
<system:String>GHI</system:String>
<system:String>JKL</system:String>
</x:Array>
</ListBox.ItemsSource>
</ListBox>
</Expander.Content>
</Expander>
基础知识
DEF
GHI
JKL
我建议您创建从ListBox派生的控件(不是usercontrol)。
我有硬编码的数据模板,但您应该在自定义依赖项属性中公开它们,并在控制模板中使用TemplateBinding。当然,您需要修改expander,使其看起来像combobox和ListBoxItem样式,使其看起来像CheckBox,但这很简单。在您的控制模板中,使用模板绑定iso binding.isCurrences
是一种可观察到的集合吗
?顺便说一句,你不应该为你的列表设置setter。谢谢你的建议,但就我而言,我90%都在工作。。。combobox工作正常我只是在将ItemsSource从mainview传递到usercontrol时遇到一些问题…顺便说一句,我会看一看,谢谢您需要在usercontrol中创建ItemsSource DependecProperty。数据绑定你的组合框或者类似的东西:Liero如果你看我上面的代码,我已经在样式中定义了一个组合框,我刚刚创建了属性