编程语言
首页 > 编程语言> > 使用WPF C#中多个控件的组合创建自定义控件

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

作者:互联网

我想创建一个自定义控件,它应该是预定义控件的组合,如Textbox,Button,ListBox等,

请参考以下控件(只是一个样本)

<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中添加Textbox值,最后我需要来自此控件的List.

预期的定制控制(只是一个样本)

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

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

我需要一个Single控件,它应该继承这三个控件.在那我需要一个ItemsSource双向绑定.如果List< string>更新后,它应该更新ItemSource.

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

enter image description here

我不需要用户控件,我需要一个自定义控件,请帮助我……

项目源ViewModel集合甚至不更新 – 尽管ItemsSource具有值.

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>

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

注意
不要使用List作为ItemsSource.而是使用ObservableCollection,因为它自动通知View,你不必处理那个Update-Stuff

干杯

标签:c,net,wpf,xaml,custom-controls
来源: https://codeday.me/bug/20190717/1487804.html