与多个控件在WPF C#的组合创建自定义控制 [英] Create a Custom Control with the combination of multiple controls in WPF C#
问题描述
我想创建一个自定义的控制,就应该像文本框,按钮,列表框等预定义的控件的组合。
I wish to create a Custom Control, it should be a combination of predefined controls like Textbox, Button, ListBox, etc.,
请参考下控制(只是一个样本)
Kindly refer the following Controls (Just a Sample)
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" />
<Button Grid.Column="1" Content="Add" Margin="20,0" />
</Grid>
<ListBox ItemsSource="{Binding textBox}" Grid.Row="1" Margin="0,25">
<ListBoxItem />
</ListBox>
</Grid>
我需要控制在一个单一的自定义控件的组合。我需要在列表项中添加文本框的值,而我打的按钮,最后我需要从这个控制列表。
I need a combination of controls in a single custom control. I need to add the Textbox values in a ListItem while I'm hitting the button and finally I need the List from this control.
预计自定义控件(只是一个样本)
Expected Custom Control (Just a Sample)
<cust:MultiControl ItemsSource="{Binding stringCollection}" />
说明:
我需要得到的字符串列表从用户。我添加了一个文本框来获取用户输入。我添加了一个按钮来添加在文本列表<串GT;
。显示列表我添加了一个列表框。
Description:
I need to get the list of string from the user. I added a TextBox to get the input from the User. I added a Button to add the text in a List<string>
. To display the List I added a ListBox.
我需要一个单一的控制,就应该继承这些三个控件。在我需要一个的ItemsSource
对于双向结合。如果列表<字符串方式>
更新,就应该更新的ItemSource
I need a Single control, it should inherit these three controls. In that I need an ItemsSource
for two way binding. If the List<string>
is updated, it should update the ItemSource.
我使用这个结构超过15位。所以,我要让它为自定义的控制。请帮助我如何实现这个作为一个单一的控制?
I'm using this structure in more than 15 places. So, I wish to make it as Custom control. Kindly assist me how to implement this as a single control ?
我不需要用户控制,我需要一个自定义控件好心帮我...
I don't need a User Control, I need a Custom Control kindly assist me...
物品来源视图模型集合没有更新偶虽然的ItemsSource具有价值。
Item Source ViewModel Collection is not updating even-though the ItemsSource has value.
推荐答案
我做了你需要的CustomControl的小例子。
I've made you a minimal example of that desired CustomControl.
控制
public class MyCustomControl : ItemsControl {
static MyCustomControl() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
}
private Button _addButton;
private TextBox _textBox;
private ListView _itemsView;
public override void OnApplyTemplate() {
this._addButton = this.GetTemplateChild("PART_AddButton") as Button;
this._textBox = this.GetTemplateChild("PART_TextBox") as TextBox;
this._itemsView = this.GetTemplateChild("PART_ListBox") as ListView;
this._addButton.Click += (sender, args) => {
(this.ItemsSource as IList<string>).Add(this._textBox.Text);
};
this._itemsView.ItemsSource = this.ItemsSource;
base.OnApplyTemplate();
}
public ICommand DeleteCommand => new RelayCommand(x => { (this.ItemsSource as IList<string>).Remove((string)x); });
}
模板
<Style TargetType="{x:Type local:MyCustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyCustomControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBox x:Name="PART_TextBox" Grid.Column="0" />
<Button x:Name="PART_AddButton" Grid.Column="1" Content="Add" Margin="20,0" />
</Grid>
<ListView ItemsSource="{TemplateBinding ItemsSource}" Grid.Row="1" Margin="0,25" x:Name="PART_ListBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding}"/>
<Button Content="X" Foreground="Red"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyCustomControl}}, Path=DeleteCommand}"
CommandParameter="{Binding}" Margin="10,0,0,0"></Button>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
RelayCommand
public class RelayCommand : ICommand
{
#region Fields
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
{
if (execute == null)
throw new ArgumentNullException(nameof(execute));
this._execute = execute;
this._canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return this._canExecute == null || this._canExecute(parameter);
}
public event EventHandler CanExecuteChanged {
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
this._execute(parameter);
}
#endregion // ICommand Members
}
用法
<local:MyCustomControl ItemsSource="{Binding Collection}"/>
注意
不要使用列表
为您的ItemsSource。而使用的ObservableCollection
,因为它通知查看全自动和你没有处理这个更新-东西
Note
Do not use a List
as your ItemsSource. Rather use an ObservableCollection
since it notifies the View automaticly and you dont have to deal with that Update-Stuff
干杯
这篇关于与多个控件在WPF C#的组合创建自定义控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!