动态控件添加,基本UI开发都需要使用。我看过很多人写,都停留在WinFrom开发时代的直接操作控件来实现动态添加控件。到了WPF依然很多人在这样操作。
(不是说这样写错误,但是这违背了UI和逻辑分离的思想,不利于后期维护。深有体会。当看到后台密密麻麻的添加子控件,心情瞬间崩溃)
我们先来看下UI和逻辑不分离的代码(简单粗暴实现代码):
XAML代码:
XAML.cs代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace WpfApplication4{ ////// MainWindow.xaml 的交互逻辑 /// public partial class MainWindow : Window { #region << Constructor >> public MainWindow() { InitializeComponent(); //this.DataContext = new MainWindowsViewModel(); } #endregion #region << Method >> private void Button_Click_1(object sender, RoutedEventArgs e) { this.wpContainer.Children.Add(GetChild("NewChild")); } private StackPanel GetChild(string name) { StackPanel container = new StackPanel(); container.Width = 300; container.Orientation = Orientation.Horizontal; TextBlock tb = new TextBlock(); tb.Width = 120; tb.Height = 60; tb.Margin = new Thickness(4, 4, 4, 4); tb.Text = name; Button btnRead = new Button(); btnRead.Content = "Read"; btnRead.Width = 80; btnRead.Height = 60; btnRead.Margin = new Thickness(4, 4, 4, 4); Button btnWrite = new Button(); btnWrite.Content = "Write"; btnWrite.Width = 80; btnWrite.Height = 60; btnWrite.Margin = new Thickness(4, 4, 4, 4); container.Children.Add(tb); container.Children.Add(btnRead); container.Children.Add(btnWrite); return container; } #endregion }}
上面的实现动态添加控件。我直接使用路由事件(我可不想把控件传到ViewModel中,所以没用Command)
只是简单的添加,不调整布局,无样式。就有许多代码了。当我们动态添加的控件过于复杂。或者前台美工想调整布局。觉得是灾难;下面是我们使用下DataTemplate的动态添加控件。(容器使用ListView.容器样式默认(只是为了实现动态,不关心样式))
XAML代码:
XAML.cs代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace WpfApplication4{ ////// MainWindow.xaml 的交互逻辑 /// public partial class MainWindow : Window { #region << Constructor >> public MainWindow() { InitializeComponent(); this.DataContext = new MainWindowsViewModel(); } #endregion }}
后台代码很干净
ViewModel代码:
using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Input;namespace WpfApplication4{ public class MainWindowsViewModel:NotifyObject { #region << Property >> public ObservableCollectionItemList { get; set; } public ICommand ClickCommand { get; set; } #endregion #region << Constructor >> public MainWindowsViewModel() { ItemList = new ObservableCollection (); ClickCommand = new DeletegateCommand(Click); } #endregion #region << Method >> public void Click() { ItemList.Add("xx"); } #endregion }}
ViewModel代码也很干净。
相对来说,很多的代码都移到了前台页面中。所有逻辑层的代码相对来说较少。
动态添加 只要有ItemTemplate属性的控件都可以使用。(基本上)
这样写的话,主要任务就交给了美观(LIstView样式的调整)