• 为Wpf敏捷开发做准备Wpf实现Form表单2


    前言:上一节实现的FormItem中,还需要自己写TextBox或者ComboBox,代码还是比较多,我们能不能设置一个属性,让其自动生成呢?说干就干。

    第一步:实现FormCodeItem继承FormItem,定义依赖性属性ControlType,根据ControlType自动生成控件,思路很明确,代码很多。

    #region ControlType
    public static readonly DependencyProperty ControlTypeProperty = DependencyProperty.Register(
        "ControlType", typeof(FormControlType), typeof(FormCodeItem), new PropertyMetadata(FormControlType.TextBox, OnControlTypeChanged));

    private static void OnControlTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is FormCodeItem formCodeItem)
        {
            formCodeItem.GetControl((FormControlType)e.NewValue);
        }
    }

    [DisplayName("控件类型")]
    public FormControlType ControlType
    {
        get
        {
            return (FormControlType)GetValue(ControlTypeProperty);
        }
        set
        {
            SetValue(ControlTypeProperty, value);
        }
    }

    private void GetControl(FormControlType controlType)
    {
        if (_contentPresenter == null)
            return;

        bool hideHeader = false;

        
        switch (controlType)
        {
            case FormControlType.TextBox:
                {
                    _control = new TextBox() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(TextBox.TextProperty, binding);
                    }
                    break;
                }
            case FormControlType.ComboBox:
                {
                    _control = new ComboBox() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(ComboBox.SelectedValueProperty, binding);
                    }
                    _control.SetValue(ComboBox.DisplayMemberPathProperty, "Text");
                    _control.SetValue(ComboBox.SelectedValuePathProperty, "Value");
                    break;
                }
            case FormControlType.PasswordBox:
                {
                    _control = new PasswordBox() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(PasswordBoxBindingBehavior.PasswordProperty, binding);
                    }
                    break;
                }
            case FormControlType.DatePicker:
                {
                    _control = new DatePicker() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(DatePicker.SelectedDateProperty, binding);
                    }
                    break;
                }
            case FormControlType.TreeSelect:
                {
                    _control = new TreeSelect() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.Mode = BindingMode.TwoWay;
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(TreeSelect.SelectedValueProperty, binding);
                    }
                    _control.SetValue(TreeSelect.DisplayMemberPathProperty, "Text");
                    _control.SetValue(TreeSelect.SelectedValuePathProperty, "Value");

                    var dataTemplate = new HierarchicalDataTemplate();
                    dataTemplate.ItemsSource = new Binding("Children");
                    FrameworkElementFactory fef = new FrameworkElementFactory(typeof(TextBlock));
                    Binding bind = new Binding("Text");
                    fef.SetBinding(TextBlock.TextProperty, bind);
                    dataTemplate.VisualTree = fef;
                    (_control as TreeSelect).ItemTemplate = dataTemplate;
                    break;
                }
            case FormControlType.MultiComboBox:
                {
                    _control = new MultiComboBox() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.Mode = BindingMode.TwoWay;
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(CustomeSelectionValues.SelectedValuesProperty, binding);
                    }
                    _control.SetValue(ComboBox.DisplayMemberPathProperty, "Text");
                    _control.SetValue(ComboBox.SelectedValuePathProperty, "Value");
                    break;
                }
            case FormControlType.MultiTreeSelect:
                {
                    _control = new TreeSelect() { Background = Brushes.Transparent, IsMulti = true };

                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.Mode = BindingMode.TwoWay;
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(TreeSelect.SelectedValuesProperty, binding);
                    }
                    _control.SetValue(TreeSelect.DisplayMemberPathProperty, "Text");
                    _control.SetValue(TreeSelect.SelectedValuePathProperty, "Value");

                    var dataTemplate = new HierarchicalDataTemplate();
                    dataTemplate.ItemsSource = new Binding("Children");
                    FrameworkElementFactory fef = new FrameworkElementFactory(typeof(StackPanel));
                    fef.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

                    FrameworkElementFactory checkbox_fef = new FrameworkElementFactory(typeof(CheckBox));
                    fef.AppendChild(checkbox_fef);
                    Binding checkbox_bind = new Binding("IsChecked");
                    checkbox_fef.SetBinding(CheckBox.IsCheckedProperty, checkbox_bind);

                    FrameworkElementFactory textblock_fef = new FrameworkElementFactory(typeof(TextBlock));
                    fef.AppendChild(textblock_fef);
                    Binding textblock_bind = new Binding("Text");
                    textblock_fef.SetBinding(TextBlock.TextProperty, textblock_bind);
                    textblock_fef.SetValue(TextBlock.MarginProperty, new Thickness(2, 0, 0, 0));

                    dataTemplate.VisualTree = fef;
                    (_control as TreeSelect).ItemTemplate = dataTemplate;
                    break;
                }
            case FormControlType.IntegerUpDown:
                {
                    _control = new IntegerUpDown() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(IntegerUpDown.ValueProperty, binding);
                    }
                    break;
                }
            case FormControlType.LongUpDown:
                {
                    _control = new LongUpDown() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(IntegerUpDown.ValueProperty, binding);
                    }
                    break;
                }
            case FormControlType.DoubleUpDown:
                {
                    _control = new DoubleUpDown() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(IntegerUpDown.ValueProperty, binding);
                    }
                    break;
                }
            case FormControlType.DecimalUpDown:
                {
                    _control = new DecimalUpDown() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(IntegerUpDown.ValueProperty, binding);
                    }
                    break;
                }
            case FormControlType.DateTimeUpDown:
                {
                    _control = new DateTimeUpDown() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(IntegerUpDown.ValueProperty, binding);
                    }
                    break;
                }
            case FormControlType.CheckBox:
                {
                    _control = new CheckBox() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(CheckBox.IsCheckedProperty, binding);
                    }
                    break;
                }
            case FormControlType.ToggleButton:
                {
                    _control = new ToggleButton() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(ToggleButton.IsCheckedProperty, binding);
                    }
                    break;
                }
            case FormControlType.RichTextBox:
                {
                    _control = new RichTextBox() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(RichTextBox.TextProperty, binding);
                    }
                    break;
                }
            case FormControlType.UploadFile:
                {
                    _control = new UploadFile() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(UploadFile.FileProperty, binding);
                    }
                    _control.SetValue(UploadFile.UploadUrlProperty, ExtField1);
                    _control.SetValue(UploadFile.UploadTokenProperty, ExtField2);
                    break;
                }
            case FormControlType.UploadImage:
                {
                    _control = new UploadFile() { Background = Brushes.Transparent };
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(UploadFile.FileProperty, binding);
                        _control.SetValue(UploadFile.UploadFileTypeProperty, UploadFileType.Image);
                    }
                    _control.SetValue(UploadFile.UploadUrlProperty, ExtField1);
                    _control.SetValue(UploadFile.UploadTokenProperty, ExtField2);
                    break;
                }
            case FormControlType.DataGrid:
                {
                    _control = new DataGrid() { Background = Brushes.Transparent };
                    (_control as DataGrid).IsReadOnly = true;
                    if (!string.IsNullOrEmpty(Path))
                    {
                        Binding binding = new Binding(Path);
                        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        binding.ValidatesOnExceptions = true;
                        binding.ValidatesOnDataErrors = true;
                        binding.NotifyOnValidationError = true;
                        _control.SetBinding(DataGrid.ItemsSourceProperty, binding);
                    }

                    if (ExtField1 is IEnumerable<DataGridColumn> columns)
                    {
                        if (columns != null)
                        {
                            foreach (var column in columns)
                            {
                                var copy = System.Windows.Markup.XamlReader.Parse(System.Windows.Markup.XamlWriter.Save(column)) as DataGridColumn;
                                (_control as DataGrid).Columns.Add(copy);
                            }
                        }
                    }
                    else if (ExtField1 is IEnumerable<DataGridColumnConfig> columnconfigs)
                    {
                        if (columnconfigs != null)
                        {
                            foreach (var columnconfig in columnconfigs)
                            {
                                (_control as DataGrid).Columns.Add(columnconfig.GetColumn());
                            }
                        }
                    }
                    else
                    {
                        (_control as DataGrid).Columns.Add(new DataGridTextColumn()
                        {
                            Binding = new Binding("Field1"),
                            Header = "字段1",
                            Width = new DataGridLength(100, DataGridLengthUnitType.Pixel)
                        });
                        (_control as DataGrid).Columns.Add(new DataGridTextColumn()
                        {
                            Binding = new Binding("Field2"),
                            Header = "字段2",
                            Width = new DataGridLength(100, DataGridLengthUnitType.Pixel)
                        });
                        (_control as DataGrid).Columns.Add(new DataGridTextColumn()
                        {
                            Binding = new Binding("Field3"),
                            Header = "字段3",
                            Width = new DataGridLength(100, DataGridLengthUnitType.Pixel)
                        });
                        (_control as DataGrid).Columns.Add(new DataGridTextColumn()
                        {
                            Binding = new Binding("Field4"),
                            Header = "字段4",
                            Width = new DataGridLength(100, DataGridLengthUnitType.Pixel)
                        });
                    }

                    _control.SetValue(DataGridColumnsConfigAttach.ShowConfigProperty, true);
                    break;
                }
            case FormControlType.Query:
            case FormControlType.Submit:
                {
                    hideHeader = true;

                    _control = new Button();
                    Binding binding = new Binding($"DataContext.{Path}");
                    binding.RelativeSource = new RelativeSource { AncestorType = typeof(UserControl), Mode = RelativeSourceMode.FindAncestor };
                    _control.SetBinding(Button.CommandProperty, binding);
                    Binding binding2 = new Binding(".");
                    _control.SetBinding(Button.CommandParameterProperty, binding2);
                    Binding binding3 = new Binding("Header");
                    binding3.Source = this;
                    _control.SetBinding(Button.ContentProperty, binding3);
                    break;
                }
            default:
                {
                    _control = null;
                    break;
                }      

           
        }

        if (_header != null)
        {
            _header.Visibility = hideHeader ? Visibility.Collapsed : Visibility.Visible;
        }

        if (_control != null)
        {
            _control.SetCurrentValue(ControlAttach.ClearTextButtonProperty, true);
            _contentPresenter.Content = _control;
        }

        SetItemsSource(ItemsSource);
    }
    #endregion

    需要生成什么控件就需要定义一个类型,然后在cs中添加代码。

    第二步:样式实现

    <Style x:Key="AIStudio.Styles.FormCodeItem" BasedOn="{StaticResource AIStudio.Styles.FormItem}" TargetType="controls:FormCodeItem">
          <Style.Resources>
              <Style TargetType="{x:Type Button}" BasedOn="{StaticResource AIStudio.Styles.Button}" />
              <Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource AIStudio.Styles.CheckBox}" />
              <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource AIStudio.Styles.ComboBox.Underline}" />
              <Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource AIStudio.Styles.DatePicker.Underline}" />
              <Style TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource AIStudio.Styles.PasswordBox.Underline}" />
              <Style TargetType="{x:Type RadioButton}" BasedOn="{StaticResource AIStudio.Styles.RadioButton}" />
              <Style TargetType="{x:Type RichTextBox}" BasedOn="{StaticResource AIStudio.Styles.RichTextBox.Underline}" />
              <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource AIStudio.Styles.TextBox.Underline}" />
              <Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource AIStudio.Styles.ToggleButton.Switch}" />
              <Style TargetType="{x:Type controls:TreeSelect}" BasedOn="{StaticResource AIStudio.Styles.TreeSelect.Underline}" />
              <Style TargetType="{x:Type controls:MultiComboBox}" BasedOn="{StaticResource AIStudio.Styles.MultiComboBox.Underline}" />
              <Style TargetType="{x:Type controls:UploadFile}" BasedOn="{StaticResource AIStudio.Styles.UploadFile.Underline}" />
              <Style TargetType="{x:Type controls:RichTextBox}" BasedOn="{StaticResource AIStudio.Styles.RichTextBox.Underline}" />
          </Style.Resources>
      </Style>

    这样,生成的控件样式也就有了。

    如何使用

    <ac:Form 
        VerticalAlignment="Top"
        DataContext="{Binding Base_User2}"
        Margin="2">
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='UserName'}" Path="UserName" ControlType="TextBox"/>
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='Password'}" Path="Password" ControlType="PasswordBox"/>
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='Sex'}" Path="Sex" ItemsSource="SexList" ControlType="ComboBox"/>
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='Birthday'}" Path="Birthday" ControlType="DatePicker"/>
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='DepartmentId'}" Path="DepartmentId" ItemsSource="Departments" ControlType="TreeSelect"/>
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='RoleIdList'}" Path="RoleIdList" ItemsSource="RolesList" ControlType="MultiComboBox"/>
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='SelectedDuty'}" Path="SelectedDuty" ItemsSource="Duties" ControlType="ComboBox"/>
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='Email'}" Path="Email" ControlType="TextBox"/>
        <ac:FormCodeItem Header="{Binding .,Converter={StaticResource DisplayNameConverter},ConverterParameter='PhoneNumber'}" Path="PhoneNumber" ControlType="TextBox"/>
        <ac:FormCodeItem Header="提交" Path="SubmitCommand" ControlType="Submit"/>
    </ac:Form>

    是不是比FormItem用起来更方便简洁了。实现的效果和Form是一样的

    最后老规矩,上源码地址,在Controls下的Form文件夹中。

    https://gitee.com/akwkevin/AI-wpf-controls

  • 相关阅读:
    怎么与用户有效的沟通以获取用户的真实需求?
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?
    当下大部分互联网创业公司为什么都愿意采用增量模型来做开发?
    【第八周】回到起点,从头再来
    【第七周作业】项目开发心得
    【第六周作业】项目代码的编写规范
    【第五周作业】寸步难行
    【第四周作业】参加项目开发之后的一些体会
    【第三周作业】对于软件工程学的一些理解
    【第二周作业】面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?
  • 原文地址:https://www.cnblogs.com/akwkevin/p/16387731.html
Copyright © 2020-2023  润新知