WPF项目搭建
版权声明:本文为博主初学经验,未经博主允许不得转载。
一、前言
记录在学习与制作WPF过程中遇到的解决方案。
使用MVVM的优点是 数据和视图分离,双向绑定,低耦合,可重用行,相对独立的设计和逻辑;
二、配置
三、附件
- vs_enterprise.exe 在线安装 Visual Studio 2017 开发工具;
- SQLiteStudio.zip 免安装Sqlite轻量数据库操作工具;
- WPF-MVVM-Work.zip 项目源代码;
四、步骤
1. 创建项目;
2. 文件夹层级;
建文件夹:Model, ViewModel, View, Resources, Lib, Service, Common;
注:可以建文件夹,但更推荐新建类库放置以上层级;
3. 控件的使用与布局;
3.1 从工具箱中直接拖拉控件;
3.2 直接在代码中编辑控件代码;
4. 代码关联;
4.1 View与ViewModel的交互关联:
- View后台的代码关联
public MainWindow() //类名
{
InitializeComponent();
//后台代码有这句就实现了View和ViewModel的绑定
DataContext = new MainWindowViewModel();
}
- 文本的绑定
前端:<TextBox Text="{Binding TxtInput}"/>
后端:
public string TxtInput
{
get => _txtInput;
set
{
_txtInput = value;
//用RaisePropertyChanged刷新前端绑定控件的输入框文本内容
RaisePropertyChanged("TxtInput");
}
}
private string _txtInput;
- 事件的绑定
前端:<Button Content="添加" Command="{Binding BtnAddContent}"/>
后端:
public MainWindowViewModel()
{
//按钮事件与业务的衔接 也可以在BtnAddContent的Set中写
BtnAddContent = new RelayCommand(AddContent);
}
//前端绑定的 添加按钮 Command事件
public RelayCommand BtnAddContent { get; set; }
private void AddContent()
{
//按钮事件处理的业务逻辑代码
}
- 样式的绑定
<TextBox Style="{StaticResource TxbTrigger}" Tag="序号..." /> <Button Content="添加" Template="{StaticResource DefaultButton}" />
”TxbTrigger是输入框水印样式资源,DefaultButton是按钮样式资源模板;详细样式代码,查阅源码中的Resources-Style;“
4.2 数据绑定和命令绑定的代码(如果用第三方框架引用,就不需要编写以下两个方法类)
//数据绑定
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged<T>(Expression<Func<T>> action)
{
var propertyName = GetPropertyName(action);
RaisePropertyChanged(propertyName);
}
private static string GetPropertyName<T>(Expression<Func<T>> action)
{
var expression = (MemberExpression)action.Body;
var propertyName = expression.Member.Name;
return propertyName;
}
public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}
}
//命令绑定
public class RelayCommand : ICommand
{
public Action ExecuteAction; //执行方法
public Action<object> ExecuteCommand; //执行方法 带参数
public Func<object, bool> CanExecuteCommand; //执行方法的条件
public RelayCommand(Action action)// 执行事件
{
ExecuteAction = action;
}
//执行带参数的事件
public RelayCommand(Action<object> action)
{
ExecuteCommand = action;
}
//根据条件执行带参数的事件
public RelayCommand(Action<object> action, Func<object, bool> can)
{
ExecuteCommand = action;
CanExecuteCommand = can;
}
//当命令可执行状态发生改变时,应被激活
public event EventHandler CanExecuteChanged;
//用于判断命令是否可以执行
public bool CanExecute(object parameter)
{
if (ExecuteAction != null) return true;
return CanExecuteCommand == null || CanExecuteCommand(parameter);
}
//命令执行
public void Execute(object parameter)
{
if (ExecuteCommand != null) ExecuteCommand(parameter);
else ExecuteAction();
}
}
ViewModel的业务类需要继承ViewModelBase
public class MainWindowViewModel : ViewModelBase
前端的DataGrid绑定的数据需要用ObservableCollection类型定义列表;
public ObservableCollection<AddModel> AddContent
{
get => _addContent;
set
{
_addContent = value;
RaisePropertyChanged("AddContent");
}
} private ObservableCollection<AddModel> _addContent =
new ObservableCollection<AddModel>();
"AddModel"是Model中的属性类;代表DataGrid中绑定的列名指向;
DataGrid前端代码:
<DataGrid x:Name="DgTimes"
ItemsSource="{Binding AddContent}" AutoGenerateColumns="False"
SelectedItem="{Binding SelectTime,UpdateSourceTrigger=PropertyChanged}">
<DataGrid.InputBindings>
<!--双击事件-->
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding DgDoubleClick}"
CommandParameter="{Binding ElementName=DgTimes,Path=SelectedItem}"/>
<!--单击事件,也可以在SelectedItem选中事件中的set属性编辑业务代码-->
<MouseBinding Gesture="LeftClick" Command="{Binding DgClick}"
CommandParameter="{Binding ElementName=DgTimes,Path=SelectedItem}"/>
</DataGrid.InputBindings>
<DataGrid.Columns>
<DataGridTextColumn Header="序号" Binding="{Binding RowIndex}"/>
<DataGridTemplateColumn Header="勾选?" MinWidth="">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<!--图片的绑定,注意不能为null或者空值,不然会加载超慢-->
<Image Width="" Height="" Source="{Binding Photo}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="输入内容" Binding="{Binding AddContent}"/>
<DataGridTextColumn Header="时间" Binding="{Binding AddTime}"/>
</DataGrid.Columns>
</DataGrid>
注:由于整个制作项目的操作视频文件过大,如有所需,留邮箱地址给博主;
5. 执行效果;
五、注意事项
六、下篇预告