gpt4 book ai didi

c# - 使用 WPF C# 中的多个控件组合创建自定义控件

转载 作者:行者123 更新时间:2023-11-30 13:30:12 24 4
gpt4 key购买 nike

我想创建一个自定义控件,它应该是预定义控件的组合,如文本框、按钮、列表框等,

请引用以下控件(只是示例)

<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>

我需要在单个自定义控件中组合控件。我需要在按下按钮时在 ListItem 中添加文本框值,最后我需要来自此控件的列表。

预期的自定义控件(只是示例)

<cust:MultiControl ItemsSource="{Binding stringCollection}" />

描述:我需要从用户那里获取字符串列表。我添加了一个 TextBox 来获取用户的输入。我添加了一个按钮以在 List<string> 中添加文本.为了显示列表,我添加了一个列表框。

我需要一个Single控件,它应该继承这三个控件。因为我需要一个 ItemsSource用于双向绑定(bind)。如果List<string>已更新,它应该更新 ItemSource。

我在超过 15 个地方使用了这个结构。所以,我希望将其作为自定义控件。请帮助我如何将其实现为单个控件?

enter image description here

我不需要用户控件,我需要自定义控件,请帮助我...

即使 ItemsSource 具有值,Item Source ViewModel 集合也不会更新。

enter image description here

最佳答案

我已经为您提供了所需 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>

中继命令

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}"/>

注意不要使用 List 作为 ItemsSource。而是使用 ObservableCollection,因为它会自动通知 View,您不必处理该 Update-Stuff

干杯

关于c# - 使用 WPF C# 中的多个控件组合创建自定义控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38842082/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com