Devexpress-WPF初體驗


最近使用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設計的還是很友好的,使用起來比較順暢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM