最近使用wpf devexpress做一个wpf小项目,中间遇到了一些问题,这里记录下,同时也跟大家分享分享

1、devexpress安装

devexpress提供了很多控件,特别是各种形式的数据列表,做的又“花哨”,性能又好,很让人羡慕。

我安装的是20.1.3.0版本,安装完成后,devexpress会在编译器中添加项目模板和文件模板(VS又慢了不少)、

生成Demo Center ,Demo Source Code,从创建项目到控件的使用和demo源代码的查看,一条龙服务。

一、devexpress基础控件

devexpress提供了很多控件和实例项目,刚接触的时候,让人眼花缭乱啊。建议在使用前,把他们运行起来都看一遍,

这样在使用的时候能大概知道使用哪种类型的控件更合适。

二、Devexpress MVVM

1、ViewModelBese:ViewModelBese继承了BindableBase,BindableBase实现了INotifyPropertyChanged接口。

自定义绑定属性最简单的写法:

public string UserName
{
get { return GetValue<string>(); }
set { SetValue(value); }
} public ObservableCollection<ProductModel> ProductList
{
get { return GetValue<ObservableCollection<ProductModel>>(); }
set { SetValue(value); }
}

2、POCO ViewModel

已经有了个ViewModelBese为什么还需要POCO ViewModel呢?

这里的POCO是:Plain Old CLR Objects,官方给的解释,主要作用是简化你的ViewModel

POCO (Plain Old CLR Objects) View Models simplify and speed up the development process.

POCO View Models allow you to:

Define bindable properties as simple auto-implemented properties.

Create methods that function as commands at runtime.

Make properties and methods implement MVVM-specific interfaces.

This allows you to create clean, simple, maintainable, and testable MVVM code.

The POCO View Models are fully compatible with any WPF control.

You can use View Models Generated at Compile Time to generate boilerplate code for your ViewModels at compile time.

3、Messenger

跟MVVMlight的是Messenger使用差不多,但需要了解的是:

如果使用的是Messenger.Default.Register订阅消息,因为Messenger.Default是弱引用的信使,不会导致内存泄漏,因此不需要调用Messenger.Default.Unregister取消订阅

4、命令Commands

Xaml:

<Button Command="{Binding Path=TestCommand}" />

ViewModel:

public void Test(){}

public bool CanTest(){}

5、异步命令Asynchronous Commands

Xaml:

<dxlc:LayoutControl Orientation="Vertical" VerticalAlignment="Top">
<ProgressBar Minimum="0" Maximum="100" Value="{Binding Progress}" Height="20"/>
<Button Content="Calculate" Command="{Binding CalculateCommand}"/>
<Button Content="Cancel" Command="{Binding CalculateCommand.CancelCommand}"/>
</dxlc:LayoutControl>

ViewModel:

public AsyncCommand CalculateCommand { get; private set; }

async Task Calculate()
{
for(int i = 0; i <= 100; i++)
{
if(CalculateCommand.IsCancellationRequested)
{
Progress = 0;
return;
}
Progress = i;
await Task.Delay(20);
}
} int _Progress;
public int Progress
{
get { return _Progress; }
set { SetValue(ref _Progress, value); }
} public AsyncDelegateCommandsViewModel()
{
CalculateCommand = new AsyncCommand(Calculate);
}

6、消息框MessageBox

Xaml:

<dxmvvm:Interaction.Behaviors>
<dx:DXMessageBoxService x:Name="DXMessageBoxService" />
</dxmvvm:Interaction.Behaviors>

ViewModel:

IMessageBoxService MessageBoxService
{
get { return ServiceContainer.GetService<IMessageBoxService>(); }
}

使用:

MessageBoxService.ShowMessage("xxx!", "提示", MessageButton.OK, MessageIcon.Information);

7、线程管理服务DispatcherService

Xaml:

<dxmvvm:Interaction.Behaviors>
<dxmvvm:DispatcherService />
</dxmvvm:Interaction.Behaviors>

ViewModel:

IDispatcherService DispatcherService
{
get { return this.GetService<IDispatcherService>(); }
} //异步
DispatcherService.BeginInvoke( async ()=>
{
await Task.Delay(1000);
...
}); //同步
DispatcherService.Invoke(new Action(()=> { ... }));

8、导出服务Export

Service:

IExportService CustomerExportService
{
get { return GetService<IExportService>(); }
} public interface IExportService
{
void ExportToXls(string fileName);
} public class ExportService : ServiceBase, IExportService
{
public TableView View
{
get { return (TableView)GetValue(ViewProperty); }
set { SetValue(ViewProperty, value); }
} public static readonly DependencyProperty ViewProperty = DependencyProperty.Register("View", typeof(TableView), typeof(ExportService), new PropertyMetadata(null)); public void ExportToXls(string fileName)
{
if (View == null) return;
View.ExportToXls(fileName);
}
}

Xaml:

<dxmvvm:Interaction.Behaviors>
<services:ExportService View="{x:Reference View}" />
</dxmvvm:Interaction.Behaviors> <dxg:GridControl x:Name="GridControl"
dx:ScrollBarExtensions.ScrollBarMode="TouchOverlap"
AllowColumnMRUFilterList="False"
AutoExpandAllGroups="True"
DockPanel.Dock="Left"
ItemsSource="{Binding Path=Customers}"
SelectedItem="{Binding Path=SelectedCoustomer}"
ShowBorder="False">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand Command="{Binding UpdateCommand}" EventName="MouseDoubleClick" />
<dxmvvm:EventToCommand Command="{Binding SelectionChangedCommand}" EventName="SelectedItemChanged" />
</dxmvvm:Interaction.Behaviors>
<dxg:GridControl.GroupSummary>
<dxg:GridSummaryItem SummaryType="Count" />
</dxg:GridControl.GroupSummary>
<dxg:GridControl.Columns>
<dxg:GridColumn Width="1*"
Binding="{Binding Path=AutoId}"
FieldName="xxx" />
<dxg:GridColumn Width="3*"
Binding="{Binding Path=IssueTime}"
FieldName="日期">
<dxg:GridColumn.EditSettings>
<dxe:DateEditSettings Mask="G" MaskUseAsDisplayFormat="True" />
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem Alignment="Right" SummaryType="Count" />
<dxg:GridSummaryItem FieldName="FullName" SummaryType="Count" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.View>
<dxg:TableView x:Name="View"
AllowBestFit="True"
AllowCascadeUpdate="True"
AllowDragDrop="False"
AllowFixedGroups="True"
AllowPrintColumnHeaderImage="True"
AllowScrollAnimation="True"
BestFitMode="Smart"
HighlightItemOnHover="True"
NavigationStyle="Row"
ShowFixedTotalSummary="True"
UseLegacyFilterPanel="False" />
</dxg:GridControl.View>
</dxg:GridControl>

viewmodel:

CustomerExportService.ExportToXls(@"Files\customer.xls");

9、加载控件LoadingDecorator

Xaml:

<dx:LoadingDecorator IsSplashScreenShown="{Binding Path=IsLoading}"
OwnerLock="Full"
SplashScreenLocation="CenterWindow">
...
</dx:LoadingDecorator>

ViewModel:

public virtual bool IsLoading
{
get { return GetValue<bool>(nameof(IsLoading)); }
set { SetValue(value, nameof(IsLoading)); }
}

9、IOC容器Castle.Windsor

//集成Castle.Windsor
public class IocManager
{
private static IWindsorContainer _Instance;
private static readonly object syncRoot = new object(); private IocManager()
{
} public static IWindsorContainer Instance
{
get
{
lock (syncRoot)
{
if (_Instance == null)
{
_Instance = new WindsorContainer().Install(FromAssembly.This());
}
return _Instance;
}
}
}
} //注册(具体需要注册哪些实例,根据需要来定,这里举个例子)
IocManager.Instance.Register(
//view
Component.For<MainWindow>().LifestyleSingleton(), //viewmodel
Component.For<MainViewModel>().LifestyleSingleton(), //service
Component.For<ILoginService, LoginService>().LifestyleTransient()); //使用
MainWindow = IocManager.Instance.Resolve<MainWindow>();
MainWindow.ShowDialog();

10、集成log4net

首先需要配置好log4net,然后再结合Castle.Windsor的Logging Facility,将log4net注入到Castle.Windsor的容器中

注入:

IocManager.Instance.AddFacility<LoggingFacility>(p => p.LogUsing<Log4netFactory>().WithConfig("log4net.config"));

使用:

private ILogger logger = NullLogger.Instance;

public ILogger Logger
{
get { return logger; }
set { logger = value; }
} Logger.Info("Castle.Windsor Logging Facilityd的使用");

总的来说Devexpress设计的还是很友好的,使用起来比较顺畅。

最新文章

  1. LeetCode Design Hit Counter
  2. struts2 javaweb 过滤器、监听器 拦截器 原理
  3. ubuntu 环境变量修改和恢复总结[收藏]
  4. SpringMVC框架入门配置 IDEA下搭建Maven项目
  5. 实验室 Linux 集群的管理常用命令
  6. Servlet容器的启动过程
  7. 【Java】Java里String 的equals和==
  8. Scut 进阶:网络模型拓扑
  9. mac terminal的使用技巧
  10. JS中特殊句子-for in
  11. JS获取URL参数的值
  12. PHP-学习之路1
  13. BZOJ 1432: [ZJOI2009]Function(新生必做的水题)
  14. class AClass&lt;E extends Comparable&gt;与class AClass&lt;E extends Comaprable&lt;E&gt;&gt;有什么区别?
  15. [UnityShader基础]06.#pragma multi_compile
  16. JavaBasic_06
  17. 服务网关Zuul
  18. php修改文件上传大小限制
  19. [mysql] 关联查询sql记录
  20. 【python】利用scipy进行层次聚类

热门文章

  1. [刷题] 102 Binary Tree Level Order Traversal
  2. 【转载】有图 KVM折腾记..
  3. Hive 默认分隔符
  4. linux进阶之子网划分
  5. 10.6 ip:网络配置工具
  6. exit()和_exit()的区别
  7. SpringBoot基础学习(一) SpringBoot概念、简单案例实现、单元测试及热部署讲解
  8. 微信小程序在ios系统不兼容new Date(&#39;yyyy-mm-dd&#39;)
  9. 三:.net core(.NET 6)给swagger添加文档注释详细步骤
  10. 孔乙己,一名ERP顾问