DevExpress v24.1 Update — Your Feedback Matters
Our What's New in v24.1 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.
Lesson 4 - Show Sparkline Charts in Grid Cells
- 90 minutes to read
In this lesson, you will learn how to create a custom data query for collection views, how to use this query to show sparklines in the main grid and how to show detail collections for the selected item outside the grid.
#Step 1 - Customize the GridControl
Change the grid column layout for CustomerCollectionView in the DevExpress.HybridApp project, as described in the previous lesson.
#Step 2 - Create custom data query
In addition to properties that are present in the Customer object, let’s add two unbound properties:
- TotalSales representing overall sales for a customer;
- MonthlySales which is a collection of values representing monthly sales.
There are many ways to achieve this. For example, we can use the GridControl.CustomUnboundColumnData event to load the necessary data dynamically. This approach, however, has at least two serious drawbacks:
- a lot of queries to the database will be performed, which may affect performance;
- this does not comply with the MVVM paradigm, since we move a lot of logic to the view and make it control-dependent.
Let’s perform this task on the view model level using the projections mechanism. This will allow us to utilize any visual control to represent data and use unit-tests during development.
Create a class with existing Customer‘s properties that should be shown in the grid and two additional unbound properties.
public class CustomerInfo {
public long Id { get; set; }
public string Name { get; set; }
public string AddressLine { get; set; }
public string AddressCity { get; set; }
public StateEnum AddressState { get; set; }
public string AddressZipCode { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public decimal? TotalSales { get; set; }
public IEnumerable<decimal> MonthlySales { get; set; }
}
Note that this class contains the Id property that is not presented in the UI and which is necessary for the CollectionViewModel class to work with the CustomerInfo class as a projection type.
Create a helper method that creates the IQueryable<CustomerInfo> projection based on IQueryable<Customer>:
public static class QueriesHelper {
public static IQueryable<CustomerInfo> GetCustomerInfo(IQueryable<Customer> customers) {
return customers.Select(x => new CustomerInfo
{
Id = x.Id,
Name = x.Name,
AddressLine = x.AddressLine,
AddressCity = x.AddressCity,
AddressState = x.AddressState,
AddressZipCode = x.AddressZipCode,
Phone = x.Phone,
Fax = x.Fax,
TotalSales = x.Orders.Sum(orderItem => orderItem.TotalAmount),
MonthlySales = x.Orders.GroupBy(o => o.OrderDate.Month).Select(g => g.Sum(i => i.TotalAmount)),
});
}
}
To make CustomerCollectionViewModel work with CustomerInfo as a projection type, specify it as an additional generic parameter in the base class and use the GetCustomerInfo helper method to pass a projection parameter:
public partial class CustomerCollectionViewModel : CollectionViewModel<Customer, CustomerInfo, long, IDevAVDbUnitOfWork> {
//...
protected CustomerCollectionViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Customers, query => QueriesHelper.GetCustomerInfo(query)) {
}
}
Since the CustomerInfo property names match the corresponding properties in the Customer class, you do not need to change column field names.
#Step 3 - Customizing summaries
Enable a total summary for the TotalSales property. In the designer view, select the grid, invoke the TotalSummary editor from Property Grid window, add a new GridSummary item and customize it as shown below:
Run the application.
#Step 4- Adding Sparkline Column to the Grid
Select a grid, open its smart tag and click the Add Empty Column option.
Select the added column, open its smart tag, set the ColumnBase.FieldName property to MonthlySales, change the ColumnBase.EditSettings type to SparklineEditSettings, and set its BaseEdit.StyleSettings to BarSparklineStyleSettings.
Run the application.
#Step 5- Adding Lazy Detail Collection to the Projection Type
Let’s display customer stores for the selected customer under the grid. If you use the original Customer object in the CustomerCollectionViewModel, the solution is straightforward: just bind to the Customer.CustomerStores navigation collection. This is a lazy property, so stores for the customer are loaded only when the customer is selected in the grid and the CustomerStores property for this customer is accessed.
However, you are using the CustomerInfo projection type, so you need to add and assign this property manually:
public class CustomerInfo {
...
public IEnumerable<CustomerStore> CustomerStores { get; set; }
}
public static IQueryable<CustomerInfo> GetCustomerInfo(IQueryable<Customer> customers) {
return customers.Select(x => new CustomerInfo
{
...
CustomerStores = x.CustomerStores,
});
}
This works, but all detail collections of customers stores are now loaded at once when querying to the IQueryable<CustomerInfo>. This causes performance issues because a lot of unnecessary data is loaded.
To avoid this behavior and load customer stores only for records that are selected by the customer, do the following.
Make the CustomerInfo.CustomerStores property lazy.
public class CustomerInfo {
...
Lazy<IEnumerable<CustomerStore>> customerStores;
public IEnumerable<CustomerStore> CustomerStores { get { return customerStores.Value; } }
public void SetDeferredStores(Func<IEnumerable<CustomerStore>> getStores) {
this.customerStores = new Lazy<IEnumerable<CustomerStore>>(getStores);
}
}
Provide a method that assigns a function to be used for obtaining customer stores to the collection of the CustomerInfo object:
public static class QueriesHelper {
...
public static void UpdateCustomerInfoStores(IEnumerable<CustomerInfo> entities, IQueryable<Customer> customers) {
foreach(var item in entities) {
item.SetDeferredStores(() => customers.First(x => x.Id == item.Id).CustomerStores.ToArray());
}
}
}
The CollectionViewModel class provides a special virtual method that is called when one or many entities have been loaded from the database:
partial class CustomerCollectionViewModel {
protected override void OnEntitiesLoaded(IDevAVDbUnitOfWork unitOfWork, IEnumerable<CustomerInfo> entities) {
base.OnEntitiesLoaded(unitOfWork, entities);
QueriesHelper.UpdateCustomerInfoStores(entities, unitOfWork.Customers);
}
}
Now, you can use the CustomerInfo.CustomerStores collection in the UI and it will be loaded on demand.
#Step 6 - Using SlideView Control to Display Detail Collections
Place the SlideView control from the property grid under the GridControl. Assign the following ItemTemplate and ItemContainerStyle to it:
<dxwui:SlideView.ItemTemplate>
<DataTemplate>
<Border Background="Transparent">
<Grid Margin="0,0,16,0" Width="120">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<dxe:ImageEdit Height="120" IsReadOnly="True" EditValue="{Binding CrestLarge}" ShowBorder="False" />
<StackPanel Grid.Row="1" HorizontalAlignment="Center" Margin="0,5,0,0" TextBlock.FontSize="12">
<Label Content="{Binding AddressCity}" HorizontalAlignment="Center" />
<Label Content="{Binding AddressLine}" HorizontalAlignment="Center" />
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</dxwui:SlideView.ItemTemplate>
<dxwui:SlideView.ItemContainerStyle>
<Style TargetType="dxwui:SlideViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dxwui:SlideViewItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</dxwui:SlideView.ItemContainerStyle>
Select the SildeView and open its smart tag. Set the SlideView.ShowBackButton property to false and bind the ItemsSource property to SelectedItem.CustomerStores using Binding Editor.
Run the application.
#Result
- Employee.cs
- Product.cs
- ValidationAttributes.cs
- QueriesHelper.cs
- Customer.cs
- ProductCollectionViewModel.cs
- SingleObjectViewModel.cs
- UnitOfWorkSource.cs
- OrderCollectionView.xaml.cs
- DevAVDbView.xaml.cs
- CustomerCollectionViewModel.cs
- EmployeeTask.cs
- QuoteCollectionViewModel.cs
- DatabaseObject.cs
- FilterInfo.cs
- EmployeeView.xaml.cs
- OrderViewModel.cs
- EmployeeTaskCollectionView.xaml.cs
- OrderView.xaml.cs
- CustomerCollectionViewModel.partial.cs
- Quote.cs
- EmployeeCollectionView.xaml.cs
- FilterItem.cs
- ISupportFiltering.cs
- ProductView.xaml.cs
- CollectionViewModel.cs
- OrderCollectionViewModel.cs
- EmployeeTaskViewModel.cs
- IDevAVDbUnitOfWork.cs
- FilterTreeViewModel.cs
- CustomerStore.cs
- FiltersSettings.cs
- CustomerCollectionView.xaml.cs
- EntitiesViewModel.cs
- DesignTimeDevAVDbUnitOfWork.cs
- EmployeeTaskView.xaml.cs
- IFilterTreeModelPageSpecificSettings.cs
- CustomFilterView.xaml.cs
- ReadOnlyCollectionViewModel.cs
- Order.cs
- CustomerInfo.cs
- DevAVDbUnitOfWork.cs
- ProductCollectionView.xaml.cs
- DatabaseGenerator.cs
- DevAVDb.cs
- CustomerView.xaml.cs
- EmployeeViewModel.cs
- DevAVDbViewModel.cs
- CustomerViewModel.cs
- StateEnum.cs
- HorizontalScrollingOnMouseWheelBehavior.cs
- QuoteViewModel.cs
- MainWindow.xaml.cs
- CustomFilterViewModel.cs
- EmployeeTaskCollectionViewModel.cs
- DevAVDbMetadata.cs
- InstantFeedbackCollectionViewModel.cs
- CollectionViewModel.partial.cs
- FilterTreeModelPageSpecificSettings.cs
- QuoteView.xaml.cs
- ProductViewModel.cs
- QuoteCollectionView.xaml.cs
- EmployeeCollectionViewModel.cs
- DatabaseInitializer.cs
- LoadingSplashScreen.xaml.cs
- Converters.cs
- GenerateDBSplashScreen.xaml.cs
- StaticFiltersPanel.xaml.cs
- LoadingSplashScreen.xaml
- StaticFiltersPanel.xaml
- OrderView.xaml
- CustomerCollectionView.xaml
- QuoteView.xaml
- QuoteCollectionView.xaml
- ProductView.xaml
- EmployeeTaskView.xaml
- EmployeeView.xaml
- GenerateDBSplashScreen.xaml
- MainWindow.xaml
- ProductCollectionView.xaml
- EmployeeCollectionView.xaml
- EntityViewResources.xaml
- DevAVDbView.xaml
- CollectionViewResources.xaml
- OrderCollectionView.xaml
- EmployeeTaskCollectionView.xaml
- CustomerView.xaml
- CustomFilterView.xaml
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using DevExpress.DataAnnotations;
namespace DevExpress.DevAV {
public class Employee : DatabaseObject {
public Employee() {
AssignedTasks = new List<EmployeeTask>();
}
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public PersonPrefix Prefix { get; set; }
[Phone]
public string HomePhone { get; set; }
[Required, Phone]
public string MobilePhone { get; set; }
[Required, EmailAddress]
public string Email { get; set; }
public string Skype { get; set; }
public DateTime? BirthDate { get; set; }
public byte[] Picture { get; set; }
public StateEnum AddressState { get; set; }
public string AddressLine { get; set; }
public string AddressCity { get; set; }
public string AddressZipCode { get; set; }
public EmployeeDepartment Department { get; set; }
[Required]
public string Title { get; set; }
public EmployeeStatus Status { get; set; }
public DateTime? HireDate { get; set; }
public virtual List<EmployeeTask> AssignedTasks { get; set; }
public string PersonalProfile { get; set; }
public override string ToString() {
return FirstName + " " + LastName;
}
public virtual int Order { get; set; }
public string FullName
{
get { return string.Format("{0} {1}", FirstName, LastName); }
}
public string AddressCityLine
{
get { return GetCityLine(AddressCity, AddressState, AddressZipCode); }
}
internal static string GetCityLine(string city, StateEnum state, string zipCode) {
return string.Format("{0}, {1} {2}", city, state, zipCode);
}
}
public enum PersonPrefix {
Dr,
Mr,
Ms,
Miss,
Mrs,
}
public enum EmployeeStatus {
Salaried,
Commission,
Contract,
Terminated,
OnLeave
}
public enum EmployeeDepartment {
[Display(Name = "Sales")]
Sales = 1,
[Display(Name = "Support")]
Support,
[Display(Name = "Shipping")]
Shipping,
[Display(Name = "Engineering")]
Engineering,
[Display(Name = "Human Resources")]
HumanResources,
[Display(Name = "Management")]
Management,
[Display(Name = "IT")]
IT
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace DevExpress.DevAV {
public class Product : DatabaseObject {
public string Name { get; set; }
public string Description { get; set; }
public DateTime ProductionStart { get; set; }
public bool Available { get; set; }
public byte[] Image { get; set; }
public virtual Employee Support { get; set; }
public long? SupportId { get; set; }
public virtual Employee Engineer { get; set; }
public long? EngineerId { get; set; }
public int? CurrentInventory { get; set; }
public int Backorder { get; set; }
public int Manufacturing { get; set; }
public byte[] Barcode { get; set; }
[DataType(DataType.Currency)]
public decimal Cost { get; set; }
[DataType(DataType.Currency)]
public decimal SalePrice { get; set; }
[DataType(DataType.Currency)]
public decimal RetailPrice { get; set; }
public double ConsumerRating { get; set; }
public ProductCategory Category { get; set; }
}
public enum ProductCategory {
[Display(Name = "Automation")]
Automation,
[Display(Name = "Monitors")]
Monitors,
[Display(Name = "Projectors")]
Projectors,
[Display(Name = "Televisions")]
Televisions,
[Display(Name = "Video Players")]
VideoPlayers,
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
// This demo targets .NET Framework 4.0. A number of validation attributes that exist in .NET Framework 4.5 cannot be used.
// That is why we have created our own counterparts of these attributes for this demo.
// If your application targets .NET Framework 4.5, use default validation attributes.
// If your application targets .NET Framework 4.0, you can copy and use these attributes or use DevExpress Validation Fluent API instead.
namespace DevExpress.DataAnnotations {
public abstract class RegexAttributeBase : DataTypeAttribute {
protected const RegexOptions DefaultRegexOptions = RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase;
readonly Regex regex;
public RegexAttributeBase(string regex, string defaultErrorMessage, DataType dataType)
: this(new Regex(regex, DefaultRegexOptions), defaultErrorMessage, dataType) {
}
public RegexAttributeBase(Regex regex, string defaultErrorMessage, DataType dataType)
: base(dataType) {
this.regex = (Regex)regex;
this.ErrorMessage = defaultErrorMessage;
}
public sealed override bool IsValid(object value) {
if(value == null)
return true;
string input = value as string;
return input != null && regex.Match(input).Length > 0;
}
}
public sealed class PhoneAttribute : RegexAttributeBase {
static readonly Regex regex = new Regex(@"^(\+\s?)?((?<!\+.*)\(\+?\d+([\s\-\.]?\d+)?\)|\d+)([\s\-\.]?(\(\d+([\s\-\.]?\d+)?\)|\d+))*(\s?(x|ext\.?)\s?\d+)?$", DefaultRegexOptions);
const string Message = "The {0} field is not a valid phone number.";
public PhoneAttribute()
: base(regex, Message, DataType.PhoneNumber) {
}
}
public sealed class EmailAddressAttribute : RegexAttributeBase {
static readonly Regex regex = new Regex(@"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$", DefaultRegexOptions);
const string Message = "The {0} field is not a valid e-mail address.";
public EmailAddressAttribute()
: base(regex, Message, DataType.EmailAddress) {
}
}
public sealed class UrlAttribute : RegexAttributeBase {
static Regex regex = new Regex(@"^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$", DefaultRegexOptions);
const string Message = "The {0} field is not a valid fully-qualified http, https, or ftp URL.";
public UrlAttribute()
: base(regex, Message, DataType.Url) {
}
}
public sealed class ZipCodeAttribute : RegexAttributeBase {
static Regex regex = new Regex(@"^[0-9][0-9][0-9][0-9][0-9]$", DefaultRegexOptions);
const string Message = "The {0} field is not a valid ZIP code.";
public ZipCodeAttribute()
: base(regex, Message, DataType.Url) {
}
}
public sealed class CreditCardAttribute : DataTypeAttribute {
const string Message = "The {0} field is not a valid credit card number.";
public CreditCardAttribute()
: base(DataType.Custom) {
this.ErrorMessage = Message;
}
public override bool IsValid(object value) {
if(value == null)
return true;
string stringValue = value as string;
if(stringValue == null)
return false;
stringValue = stringValue.Replace("-", "").Replace(" ", "");
int number = 0;
bool oddEvenFlag = false;
foreach(char ch in stringValue.Reverse()) {
if(ch < '0' || ch > '9')
return false;
int digitValue = (ch - '0') * (oddEvenFlag ? 2 : 1);
oddEvenFlag = !oddEvenFlag;
while(digitValue > 0) {
number += digitValue % 10;
digitValue = digitValue / 10;
}
}
return (number % 10) == 0;
}
}
}
using DevExpress.Mvvm;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DevExpress.DevAV {
public static class QueriesHelper {
public static IQueryable<CustomerInfo> GetCustomerInfo(IQueryable<Customer> customers) {
return customers.Select(x => new CustomerInfo
{
Id = x.Id,
Name = x.Name,
AddressLine = x.AddressLine,
AddressCity = x.AddressCity,
AddressState = x.AddressState,
AddressZipCode = x.AddressZipCode,
Phone = x.Phone,
Fax = x.Fax,
TotalSales = x.Orders.Sum(orderItem => orderItem.TotalAmount),
MonthlySales = x.Orders.GroupBy(o => o.OrderDate.Month).Select(g => g.Sum(i => i.TotalAmount)),
});
}
public static void UpdateCustomerInfoStores(IEnumerable<CustomerInfo> entities, IQueryable<Customer> customers) {
foreach(var item in entities) {
item.SetDeferredStores(() => customers.First(x => x.Id == item.Id).CustomerStores.ToArray());
}
}
}
}
<UserControl
x:Class="DevExpress.HybridApp.LoadingSplashScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
mc:Ignorable="d" d:DataContext="{x:Static dx:SplashScreenViewModel.DesignTimeData}">
<Grid Margin="20" Width="430">
<Grid.Effect>
<DropShadowEffect ShadowDepth="1" Direction="-90" BlurRadius="10" Opacity="0.25"/>
</Grid.Effect>
<Border Background="Black" CornerRadius="3" Opacity="0.25"/>
<Border CornerRadius="2" Margin="1" Background="White"/>
<StackPanel Orientation="Vertical" Margin="12">
<Image Source="SplashScreenBackground.png" Stretch="None"/>
<TextBlock TextWrapping="Wrap" Text="{Binding State}" Margin="12,12,12,0" Foreground="#FF2D2D2D"/>
<ProgressBar Height="14" Margin="12" IsIndeterminate="{Binding IsIndeterminate}"
Value="{Binding Progress}" Maximum="{Binding MaxProgress}"/>
</StackPanel>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using DevExpress.DataAnnotations;
namespace DevExpress.DevAV {
public partial class Customer : DatabaseObject {
public Customer() {
Orders = new List<Order>();
}
[Required]
public string Name { get; set; }
public StateEnum AddressState { get; set; }
public string AddressLine { get; set; }
public string AddressCity { get; set; }
public string AddressZipCode { get; set; }
[Phone]
public string Phone { get; set; }
[Phone]
public string Fax { get; set; }
[Url]
public string Website { get; set; }
[DataType(DataType.Currency)]
public decimal AnnualRevenue { get; set; }
public int TotalStores { get; set; }
public int TotalEmployees { get; set; }
public CustomerStatus Status { get; set; }
public virtual List<Order> Orders { get; set; }
public virtual List<Quote> Quotes { get; set; }
public virtual List<CustomerStore> CustomerStores { get; set; }
public byte[] Logo { get; set; }
}
public enum CustomerStatus {
Active,
Suspended
}
}
using System;
using System.Linq;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the Products collection view model.
/// </summary>
public partial class ProductCollectionViewModel : CollectionViewModel<Product, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of ProductCollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static ProductCollectionViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new ProductCollectionViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the ProductCollectionViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the ProductCollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected ProductCollectionViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Products) {
}
}
}
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm.ViewModel;
using DevExpress.Mvvm.DataModel;
namespace DevExpress.DevAV.Common {
/// <summary>
/// The base class for POCO view models exposing a single entity of a given type and CRUD operations against this entity.
/// This is a partial class that provides the extension point to add custom properties, commands and override methods without modifying the auto-generated code.
/// </summary>
/// <typeparam name="TEntity">An entity type.</typeparam>
/// <typeparam name="TPrimaryKey">A primary key value type.</typeparam>
/// <typeparam name="TUnitOfWork">A unit of work type.</typeparam>
public abstract partial class SingleObjectViewModel<TEntity, TPrimaryKey, TUnitOfWork> : SingleObjectViewModelBase<TEntity, TPrimaryKey, TUnitOfWork>
where TEntity : class
where TUnitOfWork : IUnitOfWork {
/// <summary>
/// Initializes a new instance of the SingleObjectViewModel class.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create the unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns the repository representing entities of a given type.</param>
/// <param name="getEntityDisplayNameFunc">An optional parameter that provides a function to obtain the display text for a given entity. If ommited, the primary key value is used as a display text.</param>
protected SingleObjectViewModel(IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory, Func<TUnitOfWork, IRepository<TEntity, TPrimaryKey>> getRepositoryFunc, Func<TEntity, object> getEntityDisplayNameFunc = null)
: base(unitOfWorkFactory, getRepositoryFunc, getEntityDisplayNameFunc) {
}
}
}
using DevExpress.DevAV;
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.DataModel.DesignTime;
using DevExpress.Mvvm.DataModel.EF6;
using System;
using System.Collections;
using System.Linq;
namespace DevExpress.DevAV.DevAVDbDataModel {
/// <summary>
/// Provides methods to obtain the relevant IUnitOfWorkFactory.
/// </summary>
public static class UnitOfWorkSource {
/// <summary>
/// Returns the IUnitOfWorkFactory implementation based on the current mode (run-time or design-time).
/// </summary>
public static IUnitOfWorkFactory<IDevAVDbUnitOfWork> GetUnitOfWorkFactory() {
return GetUnitOfWorkFactory(ViewModelBase.IsInDesignMode);
}
/// <summary>
/// Returns the IUnitOfWorkFactory implementation based on the given mode (run-time or design-time).
/// </summary>
/// <param name="isInDesignTime">Used to determine which implementation of IUnitOfWorkFactory should be returned.</param>
public static IUnitOfWorkFactory<IDevAVDbUnitOfWork> GetUnitOfWorkFactory(bool isInDesignTime) {
if(isInDesignTime)
return new DesignTimeUnitOfWorkFactory<IDevAVDbUnitOfWork>(() => new DevAVDbDesignTimeUnitOfWork());
return new DbUnitOfWorkFactory<IDevAVDbUnitOfWork>(() => new DevAVDbUnitOfWork(() => new DevAVDb()));
}
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class OrderCollectionView : UserControl {
public OrderCollectionView() {
InitializeComponent();
}
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class DevAVDbView : UserControl {
public DevAVDbView() {
InitializeComponent();
}
}
}
using System;
using System.Linq;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the Customers collection view model.
/// </summary>
public partial class CustomerCollectionViewModel : CollectionViewModel<Customer, CustomerInfo, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of CustomerCollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static CustomerCollectionViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new CustomerCollectionViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the CustomerCollectionViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the CustomerCollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected CustomerCollectionViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Customers, query => QueriesHelper.GetCustomerInfo(query)) {
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExpress.DevAV {
public class EmployeeTask : DatabaseObject {
public string Subject { get; set; }
public string Description { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? DueDate { get; set; }
public EmployeeTaskStatus Status { get; set; }
public EmployeeTaskPriority Priority { get; set; }
public int Completion { get; set; }
public bool Reminder { get; set; }
public DateTime? ReminderDateTime { get; set; }
public virtual Employee AssignedEmployee { get; set; }
public long? AssignedEmployeeId { get; set; }
public override string ToString() {
return string.Format("{0} - {1}, due {2}, {3}", Subject, Description, DueDate, Status);
}
public bool Overdue
{
get
{
if(Status == EmployeeTaskStatus.Completed || !DueDate.HasValue)
return false;
DateTime dDate = DueDate.Value.Date.AddDays(1);
if(DateTime.Now >= dDate)
return true;
return false;
}
}
}
public enum EmployeeTaskStatus {
NotStarted,
Completed,
InProgress,
NeedAssistance,
Deferred
}
public enum EmployeeTaskPriority {
Low,
Normal,
High,
Urgent
}
}
using System;
using System.Linq;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the Quotes collection view model.
/// </summary>
public partial class QuoteCollectionViewModel : CollectionViewModel<Quote, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of QuoteCollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static QuoteCollectionViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new QuoteCollectionViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the QuoteCollectionViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the QuoteCollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected QuoteCollectionViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Quotes) {
}
}
}
using DevExpress.Mvvm;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace DevExpress.DevAV {
public abstract class DatabaseObject : IDataErrorInfo {
/// <summary>
/// Primary key property for all data model objects.
/// See https://docs.microsoft.com/ef/ef6/modeling/code-first/conventions/built-in for more details.
/// </summary>
[ScaffoldColumn(false)] // Indicates that Scaffolding Wizards should not generate UI for editing and displaying this property
public long Id { get; set; }
#region IDataErrorInfo
string IDataErrorInfo.Error { get { return null; } }
string IDataErrorInfo.this[string columnName]
{
get
{
// Obtains validation attributes applied to the corresponding property and combines error reports provided by them into one.
// Since the code generated by Scaffolding Wizards supports the IDataErrorInfo interface out of the box, the error is displayed in UI.
// The Save command will also be disabled until all errors are fixed.
// To learn more about the IDataErrorInfo support in Scaffolding Wizards, refer to the https://documentation.devexpress.com/#WPF/CustomDocument17157 topic
return IDataErrorInfoHelper.GetErrorText(this, columnName);
}
}
#endregion
}
}
using System.Collections.Generic;
namespace DevExpress.DevAV.ViewModels {
public class FilterInfo {
public string Name { get; set; }
public string FilterCriteria { get; set; }
public string ImageUri { get; set; }
}
public class FilterInfoList : List<FilterInfo> {
public FilterInfoList() { }
public FilterInfoList(IEnumerable<FilterInfo> filters)
: base(filters) {
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.StaticFiltersPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxnav="http://schemas.devexpress.com/winfx/2008/xaml/navigation"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:local="clr-namespace:DevExpress.DevAV"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
x:Name="root">
<UserControl.Resources>
<Style x:Key="LeftPanelTileItemStyle" TargetType="{x:Type dxnav:TileBarItem}">
<Setter Property="Foreground" Value="#FF787878"/>
<Setter Property="BorderBrush" Value="#FFD6D6D6"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Height" Value="80"/>
<Setter Property="Width" Value="200"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="SelectionPadding" Value="0" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding EntitiesCount}" FontSize="36" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,-5,8,0" Opacity="0.6"/>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Text="{Binding Name}" FontSize="13" Margin="6,0,0,3"/>
<Image HorizontalAlignment="Left" VerticalAlignment="Top" Source="{Binding ImageUri, Converter={dxmvvm:ReflectionConverter ConvertMethodOwner={x:Type local:Converters}, ConvertMethod=LocalUriToImage}}" dxb:ImageColorizer.IsEnabled="True"
dxb:ImageColorizer.Color="{Binding Path=(TextElement.Foreground).Color, RelativeSource={RelativeSource Self}}"
Stretch="None" Margin="6,6,0,0"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#FF2F51A5"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<DockPanel>
<dxnav:TileBar DockPanel.Dock="Left"
Margin="42,-20,0,0"
Grid.Row="1"
SelectedIndex="0"
Orientation="Vertical"
Width="215"
ItemSpacing="5"
ItemsSource="{Binding FilterTreeViewModel.StaticFilters}"
SelectedItem="{Binding FilterTreeViewModel.SelectedItem}"
ItemContainerStyle="{StaticResource LeftPanelTileItemStyle}"
Padding="0"/>
</DockPanel>
</UserControl>
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class EmployeeView : UserControl {
public EmployeeView() {
InitializeComponent();
}
}
}
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the single Order object view model.
/// </summary>
public partial class OrderViewModel : SingleObjectViewModel<Order, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of OrderViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static OrderViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new OrderViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the OrderViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the OrderViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected OrderViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Orders, x => x.PONumber) {
}
/// <summary>
/// The view model that contains a look-up collection of Customers for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<Customer> LookUpCustomers
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (OrderViewModel x) => x.LookUpCustomers,
getRepositoryFunc: x => x.Customers);
}
}
/// <summary>
/// The view model that contains a look-up collection of Employees for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<Employee> LookUpEmployees
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (OrderViewModel x) => x.LookUpEmployees,
getRepositoryFunc: x => x.Employees);
}
}
/// <summary>
/// The view model that contains a look-up collection of CustomerStores for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<CustomerStore> LookUpCustomerStores
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (OrderViewModel x) => x.LookUpCustomerStores,
getRepositoryFunc: x => x.CustomerStores);
}
}
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class EmployeeTaskCollectionView : UserControl {
public EmployeeTaskCollectionView() {
InitializeComponent();
}
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class OrderView : UserControl {
public OrderView() {
InitializeComponent();
}
}
}
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV;
using System.Collections.Generic;
namespace DevExpress.DevAV.ViewModels {
partial class CustomerCollectionViewModel {
protected override void OnEntitiesLoaded(IDevAVDbUnitOfWork unitOfWork, IEnumerable<CustomerInfo> entities) {
base.OnEntitiesLoaded(unitOfWork, entities);
QueriesHelper.UpdateCustomerInfoStores(entities, unitOfWork.Customers);
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.OrderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:OrderViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/EntityViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource EntityView.RootContainer}">
<dxwui:AppBar DockPanel.Dock="Bottom" Style="{StaticResource EntityView.AppBar}">
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Save}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndClose}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndNew}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Reset}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Delete}" />
</dxwui:AppBar>
<dxlc:DataLayoutControl x:Name="layoutControl" Style="{StaticResource EntityView.DataLayoutControl}">
<dxlc:DataLayoutItem x:Name="layoutItemInvoiceNumber" Binding="{Binding InvoiceNumber, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemPONumber" Binding="{Binding PONumber, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemOrderDate" Binding="{Binding OrderDate, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemSaleAmount" Binding="{Binding SaleAmount, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemShippingAmount" Binding="{Binding ShippingAmount, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemTotalAmount" Binding="{Binding TotalAmount, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemShipDate" Binding="{Binding ShipDate, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemOrderTerms" Binding="{Binding OrderTerms, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemCustomer" Binding="{Binding Customer, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.CustomerId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpCustomers.Entities}" ValueMember="Id" DisplayMember="Name">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpCustomers.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
<dxlc:DataLayoutItem x:Name="layoutItemEmployee" Binding="{Binding Employee, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.EmployeeId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpEmployees.Entities}" ValueMember="Id" DisplayMember="FullName">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpEmployees.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
<dxlc:DataLayoutItem x:Name="layoutItemStore" Binding="{Binding Store, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.StoreId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpCustomerStores.Entities}" ValueMember="Id" DisplayMember="AddressLine">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpCustomerStores.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
</dxlc:DataLayoutControl>
</DockPanel>
</UserControl>
<UserControl x:Class="DevExpress.DevAV.Views.CustomerCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:CustomerCollectionViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/CollectionViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource CollectionView.RootContainer}">
<dxwui:AppBar Style="{StaticResource CollectionView.AppBar}" DockPanel.Dock="Bottom">
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.New}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Edit}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Delete}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Refresh}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Reports}">
<dxmvvm:Interaction.Behaviors>
<dxrudex:ReportManagerBehavior Service="{Binding ElementName=CustomerCollectionViewReportService}" ImageType="GrayScaled" />
</dxmvvm:Interaction.Behaviors>
</dxwui:AppBarButton>
<dxwui:AppBarButton Label="Custom Filter" Command="{Binding CreateCustomFilterCommand}" Glyph="pack://application:,,,/DevExpress.HybridApp;component/Resources/Toolbar/CustomFilter.png" IsEllipseEnabled="False" AllowGlyphTheming="True" GlyphStretch="None" HorizontalAlignment="Right" />
</dxwui:AppBar>
<Grid Margin="42,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<dxg:GridControl Name="gridControl" ItemsSource="{Binding Entities}" SelectedItem="{Binding SelectedEntity}" ShowBorder="True" FontSize="14" ShowLoadingPanel="{Binding IsLoading}" Margin="0,16,0,2">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand PassEventArgsToCommand="True" Command="{Binding EditCommand}" EventName="MouseDoubleClick">
<dxmvvm:EventToCommand.EventArgsConverter>
<dx:EventArgsToDataRowConverter />
</dxmvvm:EventToCommand.EventArgsConverter>
</dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<dxg:GridControl.Columns>
<dxg:GridColumn IsSmart="True" FieldName="Name" Width="135" />
<dxg:GridColumn IsSmart="True" FieldName="AddressLine" Header="Address" Width="145" />
<dxg:GridColumn IsSmart="True" FieldName="AddressCity" Header="City" Width="95" />
<dxg:GridColumn IsSmart="True" FieldName="AddressState" Header="State" Width="60">
<dxg:GridColumn.EditSettings>
<dxe:TextEditSettings HorizontalContentAlignment="Right" />
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
<dxg:GridColumn IsSmart="True" FieldName="AddressZipCode" Header="Zipcode" FixedWidth="True" Width="100" />
<dxg:GridColumn IsSmart="True" FieldName="Phone" Width="135" />
<dxg:GridColumn IsSmart="True" FieldName="Fax" Width="130" />
<dxg:GridColumn IsSmart="True" FieldName="MonthlySales" Header="Monthly Sales (FY2013)" AllowColumnFiltering="False" AllowSorting="False" MinWidth="30" Width="220">
<dxg:GridColumn.EditSettings>
<dxe:SparklineEditSettings>
<dxe:SparklineEditSettings.StyleSettings>
<dxe:BarSparklineStyleSettings />
</dxe:SparklineEditSettings.StyleSettings>
</dxe:SparklineEditSettings>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Count" FieldName="Name" DisplayFormat="{}CUSTOMER COUNT: {0}" />
<dxg:GridSummaryItem SummaryType="Sum" FieldName="TotalSales" ShowInColumn="MonthlySales" DisplayFormat="{}TOTAL SALES (FY 2013): {0:c}" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.View>
<dxg:TableView Name="tableView" AllowEditing="False" TotalSummaryPosition="Bottom" AllowPerPixelScrolling="True" AutoWidth="True" ShowIndicator="False" ShowGroupPanel="False" ShowSearchPanelMode="Never" SearchControl="{Binding ElementName=searchControl}" NavigationStyle="Row" ShowFilterPanelMode="Never" AllowMoveColumnToDropArea="False">
</dxg:TableView>
</dxg:GridControl.View>
</dxg:GridControl>
<Grid Grid.Row="1" Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Content="{Binding SelectedEntity.Name}" VerticalAlignment="Center" FontSize="17" Margin="0,10,0,10" />
<dxwui:SlideView Grid.Row="1" ShowBackButton="False" ItemsSource="{Binding SelectedEntity.CustomerStores}">
<dxwui:SlideView.ItemTemplate>
<DataTemplate>
<Border Background="Transparent">
<Grid Margin="0,0,16,0" Width="120">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<dxe:ImageEdit Height="120" IsReadOnly="True" EditValue="{Binding CrestLarge}" ShowBorder="False" />
<StackPanel Grid.Row="1" HorizontalAlignment="Center" Margin="0,5,0,0" TextBlock.FontSize="12">
<Label Content="{Binding AddressCity}" HorizontalAlignment="Center" />
<Label Content="{Binding AddressLine}" HorizontalAlignment="Center" />
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</dxwui:SlideView.ItemTemplate>
<dxwui:SlideView.ItemContainerStyle>
<Style TargetType="dxwui:SlideViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dxwui:SlideViewItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</dxwui:SlideView.ItemContainerStyle>
</dxwui:SlideView>
</Grid>
</Grid>
</DockPanel>
</UserControl>
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace DevExpress.DevAV {
public class Quote : DatabaseObject {
public string Number { get; set; }
public virtual Customer Customer { get; set; }
public long? CustomerId { get; set; }
public virtual CustomerStore CustomerStore { get; set; }
public long? CustomerStoreId { get; set; }
public virtual Employee Employee { get; set; }
public long? EmployeeId { get; set; }
public virtual DateTime Date { get; set; }
[DataType(DataType.Currency)]
public decimal SubTotal { get; set; }
[DataType(DataType.Currency)]
public decimal ShippingAmount { get; set; }
[DataType(DataType.Currency)]
public decimal Total { get; set; }
public double Opportunity { get; set; }
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class EmployeeCollectionView : UserControl {
public EmployeeCollectionView() {
InitializeComponent();
}
}
}
using System;
using DevExpress.Data.Filtering;
using DevExpress.Mvvm.POCO;
namespace DevExpress.DevAV.ViewModels {
public class FilterItem {
public static FilterItem Create(int entitiesCount, string name, CriteriaOperator filterCriteria, string imageUri) {
return ViewModelSource.Create(() => new FilterItem(entitiesCount, name, filterCriteria, imageUri));
}
protected FilterItem(int entitiesCount, string name, CriteriaOperator filterCriteria, string imageUri) {
this.Name = name;
this.FilterCriteria = filterCriteria;
this.ImageUri = imageUri;
Update(entitiesCount);
}
public virtual string Name { get; set; }
public virtual CriteriaOperator FilterCriteria { get; set; }
public virtual int EntitiesCount { get; protected set; }
public virtual string DisplayText { get; protected set; }
public virtual string ImageUri { get; protected set; }
public void Update(int entitiesCount) {
this.EntitiesCount = entitiesCount;
DisplayText = string.Format("{0} ({1})", Name, entitiesCount);
}
public FilterItem Clone() {
return FilterItem.Create(EntitiesCount, Name, FilterCriteria, ImageUri);
}
public FilterItem Clone(string name, string imageUri) {
return FilterItem.Create(EntitiesCount, name, FilterCriteria, imageUri);
}
protected virtual void OnNameChanged() {
Update(EntitiesCount);
}
}
}
using System;
using System.Linq.Expressions;
namespace DevExpress.DevAV.ViewModels {
public interface ISupportFiltering<TEntity> where TEntity : class {
Expression<Func<TEntity, bool>> FilterExpression { get; set; }
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class ProductView : UserControl {
public ProductView() {
InitializeComponent();
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.QuoteView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:QuoteViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/EntityViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource EntityView.RootContainer}">
<dxwui:AppBar DockPanel.Dock="Bottom" Style="{StaticResource EntityView.AppBar}">
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Save}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndClose}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndNew}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Reset}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Delete}" />
</dxwui:AppBar>
<dxlc:DataLayoutControl x:Name="layoutControl" Style="{StaticResource EntityView.DataLayoutControl}">
<dxlc:DataLayoutItem x:Name="layoutItemNumber" Binding="{Binding Number, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemDate" Binding="{Binding Date, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemSubTotal" Binding="{Binding SubTotal, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemShippingAmount" Binding="{Binding ShippingAmount, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemTotal" Binding="{Binding Total, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemOpportunity" Binding="{Binding Opportunity, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemCustomer" Binding="{Binding Customer, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.CustomerId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpCustomers.Entities}" ValueMember="Id" DisplayMember="Name">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpCustomers.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
<dxlc:DataLayoutItem x:Name="layoutItemCustomerStore" Binding="{Binding CustomerStore, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.CustomerStoreId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpCustomerStores.Entities}" ValueMember="Id" DisplayMember="AddressLine">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpCustomerStores.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
<dxlc:DataLayoutItem x:Name="layoutItemEmployee" Binding="{Binding Employee, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.EmployeeId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpEmployees.Entities}" ValueMember="Id" DisplayMember="FullName">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpEmployees.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
</dxlc:DataLayoutControl>
</DockPanel>
</UserControl>
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm.ViewModel;
using DevExpress.Mvvm.DataModel;
namespace DevExpress.DevAV.Common {
/// <summary>
/// The base class for a POCO view models exposing a collection of entities of a given type and CRUD operations against these entities.
/// This is a partial class that provides extension point to add custom properties, commands and override methods without modifying the auto-generated code.
/// </summary>
/// <typeparam name="TEntity">An entity type.</typeparam>
/// <typeparam name="TPrimaryKey">A primary key value type.</typeparam>
/// <typeparam name="TUnitOfWork">A unit of work type.</typeparam>
public partial class CollectionViewModel<TEntity, TPrimaryKey, TUnitOfWork> : CollectionViewModel<TEntity, TEntity, TPrimaryKey, TUnitOfWork>
where TEntity : class
where TUnitOfWork : IUnitOfWork {
/// <summary>
/// Creates a new instance of CollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns a repository representing entities of the given type.</param>
/// <param name="projection">An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data.</param>
/// <param name="newEntityInitializer">An optional parameter that provides a function to initialize a new entity. This parameter is used in the detail collection view models when creating a single object view model for a new entity.</param>
/// <param name="canCreateNewEntity">A function that is called before an attempt to create a new entity is made. This parameter is used together with the newEntityInitializer parameter.</param>
/// <param name="ignoreSelectEntityMessage">An optional parameter that used to specify that the selected entity should not be managed by PeekCollectionViewModel.</param>
public static CollectionViewModel<TEntity, TPrimaryKey, TUnitOfWork> CreateCollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IRepository<TEntity, TPrimaryKey>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TEntity>> projection = null,
Action<TEntity> newEntityInitializer = null,
Func<bool> canCreateNewEntity = null,
bool ignoreSelectEntityMessage = false,
UnitOfWorkPolicy unitOfWorkPolicy = UnitOfWorkPolicy.Individual) {
return ViewModelSource.Create(() => new CollectionViewModel<TEntity, TPrimaryKey, TUnitOfWork>(unitOfWorkFactory, getRepositoryFunc, projection, newEntityInitializer, canCreateNewEntity, ignoreSelectEntityMessage, unitOfWorkPolicy));
}
/// <summary>
/// Initializes a new instance of the CollectionViewModel class.
/// This constructor is declared protected to avoid an undesired instantiation of the CollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns a repository representing entities of the given type.</param>
/// <param name="projection">An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data.</param>
/// <param name="newEntityInitializer">An optional parameter that provides a function to initialize a new entity. This parameter is used in the detail collection view models when creating a single object view model for a new entity.</param>
/// <param name="canCreateNewEntity">A function that is called before an attempt to create a new entity is made. This parameter is used together with the newEntityInitializer parameter.</param>
/// <param name="ignoreSelectEntityMessage">An optional parameter that used to specify that the selected entity should not be managed by PeekCollectionViewModel.</param>
protected CollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IRepository<TEntity, TPrimaryKey>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TEntity>> projection = null,
Action<TEntity> newEntityInitializer = null,
Func<bool> canCreateNewEntity = null,
bool ignoreSelectEntityMessage = false,
UnitOfWorkPolicy unitOfWorkPolicy = UnitOfWorkPolicy.Individual
) : base(unitOfWorkFactory, getRepositoryFunc, projection, newEntityInitializer, canCreateNewEntity, ignoreSelectEntityMessage, unitOfWorkPolicy) {
}
}
/// <summary>
/// The base class for a POCO view models exposing a collection of entities of a given type and CRUD operations against these entities.
/// This is a partial class that provides extension point to add custom properties, commands and override methods without modifying the auto-generated code.
/// </summary>
/// <typeparam name="TEntity">A repository entity type.</typeparam>
/// <typeparam name="TProjection">A projection entity type.</typeparam>
/// <typeparam name="TPrimaryKey">A primary key value type.</typeparam>
/// <typeparam name="TUnitOfWork">A unit of work type.</typeparam>
public partial class CollectionViewModel<TEntity, TProjection, TPrimaryKey, TUnitOfWork> : CollectionViewModelBase<TEntity, TProjection, TPrimaryKey, TUnitOfWork>
where TEntity : class
where TProjection : class
where TUnitOfWork : IUnitOfWork {
/// <summary>
/// Creates a new instance of CollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns a repository representing entities of the given type.</param>
/// <param name="projection">A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.</param>
/// <param name="newEntityInitializer">An optional parameter that provides a function to initialize a new entity. This parameter is used in the detail collection view models when creating a single object view model for a new entity.</param>
/// <param name="canCreateNewEntity">A function that is called before an attempt to create a new entity is made. This parameter is used together with the newEntityInitializer parameter.</param>
/// <param name="ignoreSelectEntityMessage">An optional parameter that used to specify that the selected entity should not be managed by PeekCollectionViewModel.</param>
public static CollectionViewModel<TEntity, TProjection, TPrimaryKey, TUnitOfWork> CreateProjectionCollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IRepository<TEntity, TPrimaryKey>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TProjection>> projection,
Action<TEntity> newEntityInitializer = null,
Func<bool> canCreateNewEntity = null,
bool ignoreSelectEntityMessage = false,
UnitOfWorkPolicy unitOfWorkPolicy = UnitOfWorkPolicy.Individual) {
return ViewModelSource.Create(() => new CollectionViewModel<TEntity, TProjection, TPrimaryKey, TUnitOfWork>(unitOfWorkFactory, getRepositoryFunc, projection, newEntityInitializer, canCreateNewEntity, ignoreSelectEntityMessage, unitOfWorkPolicy));
}
/// <summary>
/// Initializes a new instance of the CollectionViewModel class.
/// This constructor is declared protected to avoid an undesired instantiation of the CollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns a repository representing entities of the given type.</param>
/// <param name="projection">A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.</param>
/// <param name="newEntityInitializer">An optional parameter that provides a function to initialize a new entity. This parameter is used in the detail collection view models when creating a single object view model for a new entity.</param>
/// <param name="canCreateNewEntity">A function that is called before an attempt to create a new entity is made. This parameter is used together with the newEntityInitializer parameter.</param>
/// <param name="ignoreSelectEntityMessage">An optional parameter that used to specify that the selected entity should not be managed by PeekCollectionViewModel.</param>
protected CollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IRepository<TEntity, TPrimaryKey>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TProjection>> projection,
Action<TEntity> newEntityInitializer = null,
Func<bool> canCreateNewEntity = null,
bool ignoreSelectEntityMessage = false,
UnitOfWorkPolicy unitOfWorkPolicy = UnitOfWorkPolicy.Individual
) : base(unitOfWorkFactory, getRepositoryFunc, projection, newEntityInitializer, canCreateNewEntity, ignoreSelectEntityMessage, unitOfWorkPolicy) {
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.QuoteCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:QuoteCollectionViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/CollectionViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource CollectionView.RootContainer}">
<dxwui:AppBar Style="{StaticResource CollectionView.AppBar}" DockPanel.Dock="Bottom">
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.New}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Edit}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Delete}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Refresh}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Reports}">
<dxmvvm:Interaction.Behaviors>
<dxrudex:ReportManagerBehavior Service="{Binding ElementName=QuoteCollectionViewReportService}" ImageType="GrayScaled" />
</dxmvvm:Interaction.Behaviors>
</dxwui:AppBarButton>
</dxwui:AppBar>
<dxg:GridControl x:Name="gridControl" Style="{StaticResource CollectionView.GridControl.Editable}">
<dxg:GridControl.View>
<dxg:TableView Style="{StaticResource CollectionView.TableView}">
<dxmvvm:Interaction.Behaviors>
<dxrudex:GridReportManagerService x:Name="QuoteCollectionViewReportService" />
</dxmvvm:Interaction.Behaviors>
</dxg:TableView>
</dxg:GridControl.View>
<dxg:GridControl.Columns>
<dxg:GridColumn IsSmart="True" FieldName="Number" />
<dxg:GridColumn IsSmart="True" FieldName="Date" />
<dxg:GridColumn IsSmart="True" FieldName="SubTotal" />
<dxg:GridColumn IsSmart="True" FieldName="ShippingAmount" />
<dxg:GridColumn IsSmart="True" FieldName="Total" />
<dxg:GridColumn IsSmart="True" FieldName="Opportunity" />
<dxg:GridColumn FieldName="Customer.Name" Header="{x:Static localization:DevAVDbResources.Quote_Customer}" ReadOnly="True" />
<dxg:GridColumn FieldName="CustomerStore.AddressLine" Header="{x:Static localization:DevAVDbResources.Quote_CustomerStore}" ReadOnly="True" />
<dxg:GridColumn FieldName="Employee.FullName" Header="{x:Static localization:DevAVDbResources.Quote_Employee}" ReadOnly="True" />
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Count" Alignment="Right" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.GroupSummary>
<dxg:GridSummaryItem SummaryType="Count" />
</dxg:GridControl.GroupSummary>
</dxg:GridControl>
</DockPanel>
</UserControl>
using System;
using System.Linq;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the Orders collection view model.
/// </summary>
public partial class OrderCollectionViewModel : CollectionViewModel<Order, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of OrderCollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static OrderCollectionViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new OrderCollectionViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the OrderCollectionViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the OrderCollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected OrderCollectionViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Orders) {
}
}
}
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the single EmployeeTask object view model.
/// </summary>
public partial class EmployeeTaskViewModel : SingleObjectViewModel<EmployeeTask, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of EmployeeTaskViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static EmployeeTaskViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new EmployeeTaskViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the EmployeeTaskViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the EmployeeTaskViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected EmployeeTaskViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Tasks, x => x.Subject) {
}
/// <summary>
/// The view model that contains a look-up collection of Employees for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<Employee> LookUpEmployees
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (EmployeeTaskViewModel x) => x.LookUpEmployees,
getRepositoryFunc: x => x.Employees);
}
}
}
}
using DevExpress.DevAV;
using DevExpress.Mvvm.DataModel;
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExpress.DevAV.DevAVDbDataModel {
/// <summary>
/// IDevAVDbUnitOfWork extends the IUnitOfWork interface with repositories representing specific entities.
/// </summary>
public interface IDevAVDbUnitOfWork : IUnitOfWork {
/// <summary>
/// The Customer entities repository.
/// </summary>
IRepository<Customer, long> Customers { get; }
/// <summary>
/// The CustomerStore entities repository.
/// </summary>
IRepository<CustomerStore, long> CustomerStores { get; }
/// <summary>
/// The Order entities repository.
/// </summary>
IRepository<Order, long> Orders { get; }
/// <summary>
/// The Employee entities repository.
/// </summary>
IRepository<Employee, long> Employees { get; }
/// <summary>
/// The EmployeeTask entities repository.
/// </summary>
IRepository<EmployeeTask, long> Tasks { get; }
/// <summary>
/// The Quote entities repository.
/// </summary>
IRepository<Quote, long> Quotes { get; }
/// <summary>
/// The Product entities repository.
/// </summary>
IRepository<Product, long> Products { get; }
}
}
<UserControl x:Class="DevExpress.DevAV.Views.ProductView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:ProductViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/EntityViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource EntityView.RootContainer}">
<dxwui:AppBar DockPanel.Dock="Bottom" Style="{StaticResource EntityView.AppBar}">
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Save}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndClose}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndNew}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Reset}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Delete}" />
</dxwui:AppBar>
<dxlc:DataLayoutControl x:Name="layoutControl" Style="{StaticResource EntityView.DataLayoutControl}">
<dxlc:DataLayoutItem x:Name="layoutItemName" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemDescription" Binding="{Binding Description, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemProductionStart" Binding="{Binding ProductionStart, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAvailable" Binding="{Binding Available, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemImage" Binding="{Binding Image, Mode=OneTime}">
<dxe:ImageEdit EditValue="{Binding Image, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" MaxHeight="200" />
</dxlc:DataLayoutItem>
<dxlc:DataLayoutItem x:Name="layoutItemCurrentInventory" Binding="{Binding CurrentInventory, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemBackorder" Binding="{Binding Backorder, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemManufacturing" Binding="{Binding Manufacturing, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemCost" Binding="{Binding Cost, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemSalePrice" Binding="{Binding SalePrice, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemRetailPrice" Binding="{Binding RetailPrice, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemConsumerRating" Binding="{Binding ConsumerRating, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemCategory" Binding="{Binding Category, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemEngineer" Binding="{Binding Engineer, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.EngineerId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpEmployees.Entities}" ValueMember="Id" DisplayMember="FullName">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpEmployees.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
<dxlc:DataLayoutItem x:Name="layoutItemSupport" Binding="{Binding Support, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.SupportId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpEmployees.Entities}" ValueMember="Id" DisplayMember="FullName">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpEmployees.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
</dxlc:DataLayoutControl>
</DockPanel>
</UserControl>
<UserControl x:Class="DevExpress.DevAV.Views.EmployeeTaskView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:EmployeeTaskViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/EntityViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource EntityView.RootContainer}">
<dxwui:AppBar DockPanel.Dock="Bottom" Style="{StaticResource EntityView.AppBar}">
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Save}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndClose}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndNew}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Reset}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Delete}" />
</dxwui:AppBar>
<dxlc:DataLayoutControl x:Name="layoutControl" Style="{StaticResource EntityView.DataLayoutControl}">
<dxlc:DataLayoutItem x:Name="layoutItemSubject" Binding="{Binding Subject, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemDescription" Binding="{Binding Description, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemStartDate" Binding="{Binding StartDate, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemDueDate" Binding="{Binding DueDate, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemStatus" Binding="{Binding Status, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemPriority" Binding="{Binding Priority, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemCompletion" Binding="{Binding Completion, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemReminder" Binding="{Binding Reminder, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemReminderDateTime" Binding="{Binding ReminderDateTime, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAssignedEmployee" Binding="{Binding AssignedEmployee, Mode=OneTime}">
<dxg:LookUpEdit Style="{StaticResource EntityView.LookUpEdit}" DataContext="{Binding ElementName=layoutControl, Path=DataContext}" EditValue="{Binding Entity.AssignedEmployeeId, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" ItemsSource="{Binding LookUpEmployees.Entities}" ValueMember="Id" DisplayMember="FullName">
<dxg:LookUpEdit.PopupContentTemplate>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl x:Name="PART_GridControl" ShowBorder="False" ShowLoadingPanel="{Binding LookUpEmployees.IsLoading}" />
</ControlTemplate>
</dxg:LookUpEdit.PopupContentTemplate>
</dxg:LookUpEdit>
</dxlc:DataLayoutItem>
</dxlc:DataLayoutControl>
</DockPanel>
</UserControl>
<UserControl x:Class="DevExpress.DevAV.Views.EmployeeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:EmployeeViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/EntityViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource EntityView.RootContainer}">
<dxwui:AppBar DockPanel.Dock="Bottom" Style="{StaticResource EntityView.AppBar}">
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Save}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndClose}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndNew}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Reset}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Delete}" />
</dxwui:AppBar>
<dxlc:DataLayoutControl x:Name="layoutControl" Style="{StaticResource EntityView.DataLayoutControl}">
<dxlc:DataLayoutItem x:Name="layoutItemFirstName" Binding="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemLastName" Binding="{Binding LastName, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemPrefix" Binding="{Binding Prefix, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemHomePhone" Binding="{Binding HomePhone, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemMobilePhone" Binding="{Binding MobilePhone, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemEmail" Binding="{Binding Email, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemSkype" Binding="{Binding Skype, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemBirthDate" Binding="{Binding BirthDate, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemPicture" Binding="{Binding Picture, Mode=OneTime}">
<dxe:ImageEdit EditValue="{Binding Picture, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" MaxHeight="200" />
</dxlc:DataLayoutItem>
<dxlc:DataLayoutItem x:Name="layoutItemAddressState" Binding="{Binding AddressState, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAddressLine" Binding="{Binding AddressLine, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAddressCity" Binding="{Binding AddressCity, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAddressZipCode" Binding="{Binding AddressZipCode, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemDepartment" Binding="{Binding Department, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemTitle" Binding="{Binding Title, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemStatus" Binding="{Binding Status, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemHireDate" Binding="{Binding HireDate, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemPersonalProfile" Binding="{Binding PersonalProfile, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemOrder" Binding="{Binding Order, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:LayoutGroup x:Name="Tabs" View="Tabs" MinHeight="250">
<dxlc:LayoutGroup Style="{StaticResource EntityView.Detail.Container}" DataContext="{Binding EmployeeAssignedTasksDetails}" dxlc:LayoutControl.TabHeader="AssignedTasks">
<dxg:GridControl x:Name="EmployeeAssignedTasksDetailsGrid" dx:DXSerializer.SerializationID="EmployeeAssignedTasksDetailsGrid" Style="{StaticResource EntityView.Detail.GridControl.Editable}">
<dxg:GridControl.View>
<dxg:TableView Style="{StaticResource EntityView.Detail.TableView}" />
</dxg:GridControl.View>
<dxg:GridControl.Columns>
<dxg:GridColumn IsSmart="True" FieldName="Subject" />
<dxg:GridColumn IsSmart="True" FieldName="Description" />
<dxg:GridColumn IsSmart="True" FieldName="StartDate" />
<dxg:GridColumn IsSmart="True" FieldName="DueDate" />
<dxg:GridColumn IsSmart="True" FieldName="Status" />
<dxg:GridColumn IsSmart="True" FieldName="Priority" />
<dxg:GridColumn IsSmart="True" FieldName="Completion" />
<dxg:GridColumn IsSmart="True" FieldName="Reminder" />
<dxg:GridColumn IsSmart="True" FieldName="ReminderDateTime" />
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Count" Alignment="Right" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.GroupSummary>
<dxg:GridSummaryItem SummaryType="Count" />
</dxg:GridControl.GroupSummary>
</dxg:GridControl>
<dxlc:LayoutGroup Orientation="Vertical" HorizontalAlignment="Right" VerticalAlignment="Top" MinWidth="100">
<Button Style="{StaticResource EntityView.Detail.Command.New}" />
<Button Style="{StaticResource EntityView.Detail.Command.Edit}" />
<Button Style="{StaticResource EntityView.Detail.Command.Delete}" />
<Button Style="{StaticResource EntityView.Detail.Command.Refresh}" />
<Button Style="{StaticResource EntityView.Detail.Command.Save}" />
<Button Style="{StaticResource EntityView.Detail.Command.Reset}" />
</dxlc:LayoutGroup>
</dxlc:LayoutGroup>
</dxlc:LayoutGroup>
</dxlc:DataLayoutControl>
</DockPanel>
</UserControl>
<UserControl
x:Class="DevExpress.DevAV.Data.Generator.GenerateDBSplashScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
mc:Ignorable="d" d:DataContext="{x:Static dx:SplashScreenViewModel.DesignTimeData}">
<Grid Margin="20" Width="430">
<Grid.Effect>
<DropShadowEffect ShadowDepth="1" Direction="-90" BlurRadius="10" Opacity="0.25"/>
</Grid.Effect>
<Border Background="Black" CornerRadius="3" Opacity="0.25"/>
<Border CornerRadius="2" Margin="1" Background="White"/>
<StackPanel Orientation="Vertical" Margin="12">
<Image Source="SplashScreenBackground.png" Stretch="None"/>
<TextBlock TextWrapping="Wrap" Text="{Binding State}" Margin="12,12,12,0" Foreground="#FF2D2D2D"/>
<ProgressBar Height="14" Margin="12" IsIndeterminate="{Binding IsIndeterminate}"
Value="{Binding Progress}" Maximum="{Binding MaxProgress}"/>
</StackPanel>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using DevExpress.Data.Filtering;
using DevExpress.Data.Utils;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.ViewModel;
namespace DevExpress.DevAV.ViewModels {
public class FilterTreeViewModel<TEntity, TPrimaryKey> : IFilterTreeViewModel where TEntity : class {
static FilterTreeViewModel() {
var enums = typeof(EmployeeStatus).Assembly.GetTypes().Where(t => t.IsEnum);
foreach(Type e in enums)
EnumProcessingHelper.RegisterEnum(e);
}
public static FilterTreeViewModel<TEntity, TPrimaryKey> Create(IFilterTreeModelPageSpecificSettings settings, IQueryable<TEntity> entities, Action<object, Action> registerEntityChangedMessageHandler) {
return ViewModelSource.Create(() => new FilterTreeViewModel<TEntity, TPrimaryKey>(settings, entities, registerEntityChangedMessageHandler));
}
readonly IQueryable<TEntity> entities;
readonly IFilterTreeModelPageSpecificSettings settings;
object viewModel;
protected FilterTreeViewModel(IFilterTreeModelPageSpecificSettings settings, IQueryable<TEntity> entities, Action<object, Action> registerEntityChangedMessageHandler) {
this.settings = settings;
this.entities = entities;
StaticFilters = CreateFilterItems(settings.StaticFilters);
CustomFilters = CreateFilterItems(settings.CustomFilters);
SelectedItem = StaticFilters.FirstOrDefault();
AllowFiltersContextMenu = true;
Messenger.Default.Register<EntityMessage<TEntity, TPrimaryKey>>(this, message => UpdateFilters()); // temporary fix
//registerEntityChangedMessageHandler(this, () => UpdateFilters());
Messenger.Default.Register<CreateCustomFilterMessage<TEntity>>(this, message => CreateCustomFilter());
UpdateFilters();
StaticCategoryName = settings.StaticFiltersTitle;
CustomCategoryName = settings.CustomFiltersTitle;
}
public virtual ObservableCollection<FilterItem> StaticFilters { get; protected set; }
public virtual ObservableCollection<FilterItem> CustomFilters { get; protected set; }
public virtual FilterItem SelectedItem { get; set; }
public virtual FilterItem ActiveFilterItem { get; set; }
public Action NavigateAction { get; set; }
public string StaticCategoryName { get; private set; }
public string CustomCategoryName { get; private set; }
public bool AllowCustomFilters { get { return settings.CustomFilters != null; } }
public bool AllowFiltersContextMenu
{
get
{
return AllowCustomFilters && allowFiltersContextMenu;
}
set
{
allowFiltersContextMenu = value;
}
}
bool allowFiltersContextMenu;
public void DeleteCustomFilter(FilterItem filterItem) {
CustomFilters.Remove(filterItem);
SaveCustomFilters();
}
public void DuplicateFilter(FilterItem filterItem) {
var newItem = filterItem.Clone("Copy of " + filterItem.Name, null);
CustomFilters.Add(newItem);
SaveCustomFilters();
}
public void ResetCustomFilters() {
if(CustomFilters.Contains(SelectedItem))
SelectedItem = null;
settings.CustomFilters = new FilterInfoList();
CustomFilters.Clear();
settings.SaveSettings();
}
public void ModifyCustomFilter(FilterItem existing) {
FilterItem clone = existing.Clone();
var filterViewModel = CreateCustomFilterViewModel(clone, true);
ShowFilter(clone, filterViewModel, () =>
{
existing.FilterCriteria = clone.FilterCriteria;
existing.Name = clone.Name;
SaveCustomFilters();
if(existing == SelectedItem)
OnSelectedItemChanged();
});
}
public void ModifyCustomFilterCriteria(FilterItem existing, CriteriaOperator criteria) {
if(!ReferenceEquals(existing.FilterCriteria, null) && !ReferenceEquals(criteria, null) && existing.FilterCriteria.ToString() == criteria.ToString())
return;
existing.FilterCriteria = criteria;
SaveCustomFilters();
if(existing == SelectedItem)
OnSelectedItemChanged();
UpdateFilters();
}
public void ResetToAll() {
SelectedItem = StaticFilters[0];
}
public void CreateCustomFilter() {
FilterItem filterItem = CreateFilterItem(string.Empty, null, null);
var filterViewModel = CreateCustomFilterViewModel(filterItem, true);
ShowFilter(filterItem, filterViewModel, () => AddNewCustomFilter(filterItem));
}
public void AddCustomFilter(string name, CriteriaOperator filterCriteria, string imageUri = null) {
AddNewCustomFilter(CreateFilterItem(name, filterCriteria, imageUri));
}
protected virtual void OnSelectedItemChanged() {
ActiveFilterItem = SelectedItem.Clone();
UpdateFilterExpression();
NavigateCore();
}
public virtual void Navigate() {
NavigateCore();
}
void NavigateCore() {
if(NavigateAction != null)
NavigateAction();
}
void IFilterTreeViewModel.SetViewModel(object viewModel) {
this.viewModel = viewModel;
var viewModelContainer = viewModel as IFilterTreeViewModelContainer<TEntity, TPrimaryKey>;
if(viewModelContainer != null)
viewModelContainer.FilterTreeViewModel = this;
UpdateFilterExpression();
}
void UpdateFilterExpression() {
ISupportFiltering<TEntity> viewModel = this.viewModel as ISupportFiltering<TEntity>;
if(viewModel != null)
viewModel.FilterExpression = ActiveFilterItem == null ? null : GetWhereExpression(ActiveFilterItem.FilterCriteria);
}
ObservableCollection<FilterItem> CreateFilterItems(IEnumerable<FilterInfo> filters) {
if(filters == null)
return new ObservableCollection<FilterItem>();
return new ObservableCollection<FilterItem>(filters.Select(x => CreateFilterItem(x.Name, CriteriaOperator.Parse(x.FilterCriteria), x.ImageUri)));
}
const string NewFilterName = @"New Filter";
void AddNewCustomFilter(FilterItem filterItem) {
if(string.IsNullOrEmpty(filterItem.Name)) {
int prevIndex = CustomFilters.Select(fi => Regex.Match(fi.Name, NewFilterName + @" (?<index>\d+)")).Where(m => m.Success).Select(m => int.Parse(m.Groups["index"].Value)).DefaultIfEmpty(0).Max();
filterItem.Name = NewFilterName + " " + (prevIndex + 1);
} else {
var existing = CustomFilters.FirstOrDefault(fi => fi.Name == filterItem.Name);
if(existing != null)
CustomFilters.Remove(existing);
}
CustomFilters.Add(filterItem);
SaveCustomFilters();
}
void SaveCustomFilters() {
settings.CustomFilters = SaveToSettings(CustomFilters);
settings.SaveSettings();
}
FilterInfoList SaveToSettings(ObservableCollection<FilterItem> filters) {
return new FilterInfoList(filters.Select(fi => new FilterInfo { Name = fi.Name, FilterCriteria = CriteriaOperator.ToString(fi.FilterCriteria) }));
}
void UpdateFilters() {
foreach(var item in StaticFilters.Concat(CustomFilters)) {
item.Update(GetEntityCount(item.FilterCriteria));
}
}
void ShowFilter(FilterItem filterItem, CustomFilterViewModel filterViewModel, Action onSave) {
if(FilterDialogService.ShowDialog(MessageButton.OKCancel, "Create Custom Filter", "CustomFilterView", filterViewModel) != MessageResult.OK)
return;
filterItem.FilterCriteria = filterViewModel.FilterCriteria;
filterItem.Name = filterViewModel.FilterName;
ActiveFilterItem = filterItem;
if(filterViewModel.Save) {
onSave();
UpdateFilters();
}
}
CustomFilterViewModel CreateCustomFilterViewModel(FilterItem existing, bool save) {
var viewModel = CustomFilterViewModel.Create(typeof(TEntity), settings.HiddenFilterProperties, settings.AdditionalFilterProperties);
viewModel.FilterCriteria = existing.FilterCriteria;
viewModel.FilterName = existing.Name;
viewModel.Save = save;
viewModel.SetParentViewModel(this);
return viewModel;
}
FilterItem CreateFilterItem(string name, CriteriaOperator filterCriteria, string imageUri) {
return FilterItem.Create(GetEntityCount(filterCriteria), name, filterCriteria, imageUri);
}
int GetEntityCount(CriteriaOperator criteria) {
return entities.Where(GetWhereExpression(criteria)).Count();
}
Expression<Func<TEntity, bool>> GetWhereExpression(CriteriaOperator criteria) {
return this.IsInDesignMode()
? CriteriaOperatorToExpressionConverter.GetLinqToObjectsWhere<TEntity>(criteria)
: CriteriaOperatorToExpressionConverter.GetGenericWhere<TEntity>(criteria);
}
IDialogService FilterDialogService { get { return this.GetRequiredService<IDialogService>("FilterDialogService"); } }
}
public interface IFilterTreeViewModelContainer<TEntity, TPrimaryKey> where TEntity : class {
FilterTreeViewModel<TEntity, TPrimaryKey> FilterTreeViewModel { get; set; }
}
public class CreateCustomFilterMessage<TEntity> where TEntity : class {
}
public interface IFilterTreeViewModel {
void SetViewModel(object content);
Action NavigateAction { get; set; }
}
}
<dx:DXWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:Views="clr-namespace:DevExpress.DevAV.Views" x:Class="DevExpress.HybridApp.MainWindow"
xmlns:local="clr-namespace:DevExpress.HybridApp"
Title="MainWindow" Height="900" Width="1300">
<dxmvvm:Interaction.Behaviors>
<dx:DXSplashScreenService SplashScreenType="local:LoadingSplashScreen" ShowSplashScreenOnLoading="True" SplashScreenStartupLocation="CenterOwner"/>
</dxmvvm:Interaction.Behaviors>
<Grid>
<Views:DevAVDbView/>
</Grid>
</dx:DXWindow>
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace DevExpress.DevAV {
[ScaffoldTable(false)]
public class CustomerStore : DatabaseObject {
public virtual Customer Customer { get; set; }
public long? CustomerId { get; set; }
public StateEnum AddressState { get; set; }
public string AddressLine { get; set; }
public string AddressCity { get; set; }
public string AddressZipCode { get; set; }
public StateEnum State { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public int TotalEmployees { get; set; }
public int SquereFootage { get; set; }
[DataType(DataType.Currency)]
public decimal AnnualSales { get; set; }
public byte[] CrestLarge { get; set; }
public byte[] CrestSmall { get; set; }
public string Location { get; set; }
public string AddressCityLine
{
get { return Employee.GetCityLine(AddressCity, AddressState, AddressZipCode); }
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.ProductCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:ProductCollectionViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/CollectionViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource CollectionView.RootContainer}">
<dxwui:AppBar Style="{StaticResource CollectionView.AppBar}" DockPanel.Dock="Bottom">
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.New}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Edit}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Delete}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Refresh}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Reports}">
<dxmvvm:Interaction.Behaviors>
<dxrudex:ReportManagerBehavior Service="{Binding ElementName=ProductCollectionViewReportService}" ImageType="GrayScaled" />
</dxmvvm:Interaction.Behaviors>
</dxwui:AppBarButton>
<dxwui:AppBarButton Label="Custom Filter" Command="{Binding CreateCustomFilterCommand}" Glyph="pack://application:,,,/DevExpress.HybridApp;component/Resources/Toolbar/CustomFilter.png" IsEllipseEnabled="False" AllowGlyphTheming="True" GlyphStretch="None" HorizontalAlignment="Right" />
</dxwui:AppBar>
<view:StaticFiltersPanel DockPanel.Dock="Left" />
<dxg:GridControl Name="gridControl" ItemsSource="{Binding Entities}" SelectedItem="{Binding SelectedEntity}" ShowLoadingPanel="{Binding IsLoading}" Margin="50,16,42,2">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand PassEventArgsToCommand="True" Command="{Binding EditCommand}" EventName="MouseDoubleClick">
<dxmvvm:EventToCommand.EventArgsConverter>
<dx:EventArgsToDataRowConverter />
</dxmvvm:EventToCommand.EventArgsConverter>
</dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<dxg:GridControl.Columns>
<dxg:GridColumn IsSmart="True" FieldName="Name" />
<dxg:GridColumn IsSmart="True" FieldName="Cost" />
<dxg:GridColumn IsSmart="True" FieldName="SalePrice" />
<dxg:GridColumn IsSmart="True" FieldName="RetailPrice" />
<dxg:GridColumn IsSmart="True" FieldName="CurrentInventory" Header="Inventory" />
<dxg:GridColumn IsSmart="True" FieldName="Backorder" />
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Sum" FieldName="CurrentInventory" DisplayFormat="{}TOTAL INVENTORY: {0}" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.GroupSummary>
<dxg:GridSummaryItem SummaryType="Count" />
</dxg:GridControl.GroupSummary>
<dxg:GridControl.View>
<dxg:TableView x:Name="tableView" ShowSearchPanelMode="Never" SearchControl="{Binding ElementName=searchControl}" AllowEditing="False" AllowPerPixelScrolling="True" AutoWidth="True" ShowGroupPanel="False" AllowColumnMoving="False" IsColumnMenuEnabled="True" TotalSummaryPosition="Bottom" ShowIndicator="False" ShowFilterPanelMode="Never" NavigationStyle="Row" />
</dxg:GridControl.View>
</dxg:GridControl>
</DockPanel>
</UserControl>
<UserControl x:Class="DevExpress.DevAV.Views.EmployeeCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:local="clr-namespace:DevExpress.DevAV"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:EmployeeCollectionViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/CollectionViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource CollectionView.RootContainer}">
<dxwui:AppBar Style="{StaticResource CollectionView.AppBar}" DockPanel.Dock="Bottom">
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.New}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Edit}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Delete}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Refresh}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Reports}">
<dxmvvm:Interaction.Behaviors>
<dxrudex:ReportManagerBehavior Service="{Binding ElementName=EmployeeCollectionViewReportService}" ImageType="GrayScaled" />
</dxmvvm:Interaction.Behaviors>
</dxwui:AppBarButton>
</dxwui:AppBar>
<view:StaticFiltersPanel DockPanel.Dock="Left" />
<ListView Name="listView" Margin="50,16,42,2" BorderThickness="0" ItemsSource="{Binding Entities}" SelectedItem="{Binding SelectedEntity}" ScrollViewer.VerticalScrollBarVisibility="Disabled" Grid.Column="1">
<dxmvvm:Interaction.Behaviors>
<local:HorizontalScrollingOnMouseWheelBehavior />
<dxmvvm:EventToCommand Command="{Binding EditCommand}" EventName="MouseDoubleClick">
<dxmvvm:EventToCommand.EventArgsConverter>
<dxmvvm:ItemsControlMouseEventArgsConverter />
</dxmvvm:EventToCommand.EventArgsConverter>
</dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="340">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderThickness="0" Height="33">
<TextBlock Text="{Binding Path=FullName}" FontWeight="Normal" Margin="12,0,12,0" VerticalAlignment="Center" />
</Border>
<Grid Grid.Row="1" Margin="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderBrush="#FFC2C4CB" BorderThickness="1">
<Image Stretch="UniformToFill" Height="150" Width="120" Source="{Binding Path=Picture}" />
</Border>
<Grid Margin="12,10,12,0" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Top">
<TextBlock Text="ADDRESS:" Foreground="#FF808080" FontSize="13" />
<TextBlock Text="{Binding Path=AddressLine}" />
<TextBlock Text="{Binding Path=AddressCityLine}" />
</StackPanel>
<StackPanel Grid.Row="1" VerticalAlignment="Top">
<TextBlock Text="PHONE:" Foreground="#FF808080" FontSize="13" />
<TextBlock Text="{Binding Path=MobilePhone}" TextTrimming="CharacterEllipsis" />
</StackPanel>
<StackPanel Grid.Row="2" VerticalAlignment="Top">
<TextBlock Text="EMAIL:" Foreground="#FF808080" FontSize="13" />
<TextBlock Text="{Binding Path=Email}" TextTrimming="CharacterEllipsis" />
</StackPanel>
</Grid>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DockPanel>
</UserControl>
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.HybridApp.Properties;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.ViewModel;
using System;
namespace DevExpress.DevAV.ViewModels {
internal static class FiltersSettings {
public static FilterTreeViewModel<EmployeeTask, long> GetTasksFilterTree(object parentViewModel) {
return FilterTreeViewModel<EmployeeTask, long>.Create(
new FilterTreeModelPageSpecificSettings<Settings>(Settings.Default, null, x => x.TasksStaticFilters, null, null),
CreateUnitOfWork().Tasks, (recipient, handler) => RegisterEntityChangedMessageHandler<EmployeeTask, long>(recipient, handler)
).SetParentViewModel(parentViewModel);
}
public static FilterTreeViewModel<Employee, long> GetEmployeesFilterTree(object parentViewModel) {
return FilterTreeViewModel<Employee, long>.Create(
new FilterTreeModelPageSpecificSettings<Settings>(Settings.Default, "Status", x => x.EmployeesStaticFilters, null, null),
CreateUnitOfWork().Employees, (recipient, handler) => RegisterEntityChangedMessageHandler<Employee, long>(recipient, handler)
).SetParentViewModel(parentViewModel);
}
public static FilterTreeViewModel<Product, long> GetProductsFilterTree(object parentViewModel) {
return FilterTreeViewModel<Product, long>.Create(
new FilterTreeModelPageSpecificSettings<Settings>(Settings.Default, "Category", x => x.ProductsStaticFilters, x => x.ProductsCustomFilters, null,
new[] {
BindableBase.GetPropertyName(() => new Product().Id),
BindableBase.GetPropertyName(() => new Product().EngineerId),
BindableBase.GetPropertyName(() => new Product().SupportId),
BindableBase.GetPropertyName(() => new Product().Support),
}),
CreateUnitOfWork().Products, (recipient, handler) => RegisterEntityChangedMessageHandler<Product, long>(recipient, handler)
).SetParentViewModel(parentViewModel);
}
public static FilterTreeViewModel<Customer, long> GetCustomersFilterTree(object parentViewModel) {
return FilterTreeViewModel<Customer, long>.Create(
new FilterTreeModelPageSpecificSettings<Settings>(Settings.Default, "Favorites", null, x => x.CustomersCustomFilters, null,
new[] {
BindableBase.GetPropertyName(() => new Customer().Id),
}),
CreateUnitOfWork().Customers, (recipient, handler) => RegisterEntityChangedMessageHandler<Customer, long>(recipient, handler)
).SetParentViewModel(parentViewModel);
}
public static FilterTreeViewModel<Order, long> GetSalesFilterTree(object parentViewModel) {
return FilterTreeViewModel<Order, long>.Create(
new FilterTreeModelPageSpecificSettings<Settings>(Settings.Default, null, null, null, null),
CreateUnitOfWork().Orders, (recipient, handler) => RegisterEntityChangedMessageHandler<Order, long>(recipient, handler)
).SetParentViewModel(parentViewModel);
}
public static FilterTreeViewModel<Quote, long> GetOpportunitiesFilterTree(object parentViewModel) {
return FilterTreeViewModel<Quote, long>.Create(
new FilterTreeModelPageSpecificSettings<Settings>(Settings.Default, null, null, null, null),
CreateUnitOfWork().Quotes, (recipient, handler) => RegisterEntityChangedMessageHandler<Quote, long>(recipient, handler)
).SetParentViewModel(parentViewModel);
}
static IDevAVDbUnitOfWork CreateUnitOfWork() {
return UnitOfWorkSource.GetUnitOfWorkFactory().CreateUnitOfWork();
}
static void RegisterEntityChangedMessageHandler<TEntity, TPrimaryKey>(object recipient, Action handler) {
Messenger.Default.Register<EntityMessage<TEntity, TPrimaryKey>>(recipient, message => handler());
}
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CollectionViewResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<!--#region Commands-->
<Style x:Key="EntityView.Command.Save" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_Save}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=Save_32x32.png}}" />
<Setter Property="Command" Value="{Binding SaveCommand}" />
</Style>
<Style x:Key="EntityView.Command.SaveAndClose" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_SaveAndClose}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=SaveAndClose_32x32.png}}" />
<Setter Property="Command" Value="{Binding SaveAndCloseCommand}" />
</Style>
<Style x:Key="EntityView.Command.SaveAndNew" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_SaveAndNew}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=SaveAndNew_32x32.png}}" />
<Setter Property="Command" Value="{Binding SaveAndNewCommand}" />
</Style>
<Style x:Key="EntityView.Command.Reset" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_Reset}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=Reset_32x32.png}}" />
<Setter Property="Command" Value="{Binding ResetCommand}" />
</Style>
<Style x:Key="EntityView.Command.Delete" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_Delete}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=Delete_32x32.png}}" />
<Setter Property="Command" Value="{Binding DeleteCommand}" />
</Style>
<Style x:Key="EntityView.Detail.Command.New" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_New}" />
<Setter Property="Command" Value="{Binding NewCommand}" />
</Style>
<Style x:Key="EntityView.Detail.Command.Edit" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_Edit}" />
<Setter Property="Command" Value="{Binding EditCommand}" />
<Setter Property="CommandParameter" Value="{Binding SelectedEntity}" />
</Style>
<Style x:Key="EntityView.Detail.Command.Delete" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_Delete}" />
<Setter Property="Command" Value="{Binding DeleteCommand}" />
<Setter Property="CommandParameter" Value="{Binding SelectedEntity}" />
</Style>
<Style x:Key="EntityView.Detail.Command.Refresh" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_Refresh}" />
<Setter Property="Command" Value="{Binding RefreshCommand}" />
</Style>
<Style x:Key="EntityView.Detail.Command.Save" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_Save}" />
<Setter Property="Command" Value="{Binding SaveCommand}" />
</Style>
<Style x:Key="EntityView.Detail.Command.Reset" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_Reset}" />
<Setter Property="Command" Value="{Binding ResetCommand}" />
</Style>
<Style x:Key="EntityView.DetailManyToMany.Command.New" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_New}" />
<Setter Property="Command" Value="{Binding CreateDetailEntityCommand}" />
<Setter Property="IsEnabled" Value="{Binding IsCreateDetailButtonVisible}" />
</Style>
<Style x:Key="EntityView.DetailManyToMany.Command.Edit" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_Edit}" />
<Setter Property="Command" Value="{Binding EditDetailEntityCommand}" />
</Style>
<Style x:Key="EntityView.DetailManyToMany.Command.Add" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_Add}" />
<Setter Property="Command" Value="{Binding AddDetailEntitiesCommand}" />
</Style>
<Style x:Key="EntityView.DetailManyToMany.Command.Delete" TargetType="Button">
<Setter Property="Content" Value="{x:Static localization:ViewResources.Command_Delete}" />
<Setter Property="Command" Value="{Binding RemoveDetailEntitiesCommand}" />
</Style>
<!--#endregion Commands-->
<!--#region AppBar-->
<Style x:Key="EntityView.AppBar" BasedOn="{StaticResource CollectionView.AppBar}" TargetType="dxwui:AppBar" />
<!--#endregion AppBar-->
<!--#region Containers-->
<Style x:Key="EntityView.RootContainer" TargetType="FrameworkElement">
<Setter Property="dxmvvm:Interaction.BehaviorsTemplate">
<Setter.Value>
<DataTemplate>
<ItemsControl>
<dxmvvm:EventToCommand Event="Loaded" Command="{Binding OnLoadedCommand}" />
<dxwui:WinUIMessageBoxService />
<dxmvvm:LayoutSerializationService />
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="EntityView.DataLayoutControl" TargetType="dxlc:DataLayoutControl">
<Setter Property="CurrentItem" Value="{Binding Entity}" />
<Setter Property="AutoGenerateItems" Value="False" />
<Setter Property="Orientation" Value="Vertical" />
<Setter Property="IsEnabled" Value="{Binding Entity, Converter={dxmvvm:ObjectToBooleanConverter}}" />
<Setter Property="Margin" Value="0,0,0,16" />
<Setter Property="Padding" Value="67,0,43,0" />
<Setter Property="dxmvvm:Interaction.BehaviorsTemplate">
<Setter.Value>
<DataTemplate>
<ItemsControl>
<dxmvvm:EventToCommand Event="{x:Static Binding.SourceUpdatedEvent}" Command="{Binding UpdateCommand}" />
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="EntityView.LookUpEdit" TargetType="dxg:LookUpEdit">
<Setter Property="AllowUpdateTwoWayBoundPropertiesOnSynchronization" Value="False" />
<Setter Property="IsTextEditable" Value="False" />
</Style>
<Style x:Key="EntityView.Detail.Container" TargetType="FrameworkElement">
<Setter Property="dxb:MergingProperties.AllowMerging" Value="False" />
<Setter Property="dxb:BarNameScope.IsScopeOwner" Value="True" />
</Style>
<Style x:Key="EntityView.DetailManyToMany.Container" BasedOn="{StaticResource EntityView.Detail.Container}" TargetType="FrameworkElement">
<Setter Property="dxmvvm:Interaction.BehaviorsTemplate">
<Setter.Value>
<DataTemplate>
<ItemsControl>
<dx:DialogService DialogWindowStartupLocation="CenterOwner">
<dx:DialogService.DialogStyle>
<Style TargetType="Window">
<Setter Property="Width" Value="600" />
<Setter Property="Height" Value="400" />
<Setter Property="ResizeMode" Value="NoResize" />
<Setter Property="ShowInTaskbar" Value="False" />
<Setter Property="WindowStyle" Value="ToolWindow" />
</Style>
</dx:DialogService.DialogStyle>
<dx:DialogService.ViewTemplate>
<DataTemplate>
<dxg:GridControl ItemsSource="{Binding AvailableEntities}" SelectedItems="{Binding SelectedEntities}" SelectionMode="Row" ShowBorder="False" AutoGenerateColumns="RemoveOld" EnableSmartColumnsGeneration="True">
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Count" Alignment="Right" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.View>
<dxg:TableView AllowEditing="False" ShowFixedTotalSummary="True" AllowPerPixelScrolling="True" ShowGroupPanel="False" AutoWidth="True" />
</dxg:GridControl.View>
</dxg:GridControl>
</DataTemplate>
</dx:DialogService.ViewTemplate>
</dx:DialogService>
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion Containers-->
<!--#region GridControl-->
<Style x:Key="EntityView.Detail.GridControl.Editable" BasedOn="{StaticResource CollectionView.GridControl.Editable}" TargetType="dxg:GridControl">
<Setter Property="ShowBorder" Value="True" />
<Setter Property="Margin" Value="0" />
<Setter Property="MaxHeight" Value="2000" />
</Style>
<Style x:Key="EntityView.Detail.GridControl.ReadOnly" BasedOn="{StaticResource CollectionView.GridControl.ReadOnly}" TargetType="dxg:GridControl">
<Setter Property="ShowBorder" Value="True" />
<Setter Property="Margin" Value="0" />
<Setter Property="MaxHeight" Value="2000" />
</Style>
<Style x:Key="EntityView.Detail.TableView" BasedOn="{StaticResource CollectionView.TableView}" TargetType="dxg:TableView">
<Setter Property="ShowGroupPanel" Value="False" />
</Style>
<Style x:Key="EntityView.DetailManyToMany.GridControl" TargetType="dxg:GridControl">
<Setter Property="ItemsSource" Value="{Binding DetailEntities}" />
<Setter Property="SelectedItems" Value="{Binding SelectedEntities}" />
<Setter Property="AutoGenerateColumns" Value="RemoveOld" />
<Setter Property="EnableSmartColumnsGeneration" Value="True" />
<Setter Property="SelectionMode" Value="Row" />
<Setter Property="ShowBorder" Value="False" />
<Setter Property="dxmvvm:Interaction.BehaviorsTemplate">
<Setter.Value>
<DataTemplate>
<ItemsControl>
<dxmvvm:EventToCommand EventName="MouseDoubleClick" Command="{Binding EditDetailEntityCommand}" MarkRoutedEventsAsHandled="True" />
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="EntityView.DetailManyToMany.TableView" TargetType="dxg:TableView">
<Setter Property="AllowEditing" Value="False" />
<Setter Property="ShowFixedTotalSummary" Value="True" />
<Setter Property="AllowPerPixelScrolling" Value="True" />
<Setter Property="ShowGroupPanel" Value="False" />
<Setter Property="AutoWidth" Value="True" />
</Style>
<!--#endregion GridControl-->
</ResourceDictionary>
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class CustomerCollectionView : UserControl {
public CustomerCollectionView() {
InitializeComponent();
}
}
}
using System;
using System.Linq;
using System.Linq.Expressions;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm.ViewModel;
using DevExpress.Mvvm.DataModel;
namespace DevExpress.DevAV.Common {
/// <summary>
/// The base class for POCO view models exposing a collection of entities of the given type.
/// This is a partial class that provides an extension point to add custom properties, commands and override methods without modifying the auto-generated code.
/// </summary>
/// <typeparam name="TEntity">A repository entity type.</typeparam>
/// <typeparam name="TProjection">A projection entity type.</typeparam>
/// <typeparam name="TUnitOfWork">A unit of work type.</typeparam>
public abstract partial class EntitiesViewModel<TEntity, TProjection, TUnitOfWork> :
EntitiesViewModelBase<TEntity, TProjection, TUnitOfWork>
where TEntity : class
where TProjection : class
where TUnitOfWork : IUnitOfWork {
/// <summary>
/// Initializes a new instance of the EntitiesViewModel class.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns a repository representing entities of the given type.</param>
/// <param name="projection">A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.</param>
protected EntitiesViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IReadOnlyRepository<TEntity>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TProjection>> projection,
UnitOfWorkPolicy unitOfWorkPolicy)
: base(unitOfWorkFactory, getRepositoryFunc, projection, unitOfWorkPolicy) {
}
}
}
using DevExpress.DevAV;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.DataModel.DesignTime;
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExpress.DevAV.DevAVDbDataModel {
/// <summary>
/// A DevAVDbDesignTimeUnitOfWork instance that represents the design-time implementation of the IDevAVDbUnitOfWork interface.
/// </summary>
public class DevAVDbDesignTimeUnitOfWork : DesignTimeUnitOfWork, IDevAVDbUnitOfWork {
/// <summary>
/// Initializes a new instance of the DevAVDbDesignTimeUnitOfWork class.
/// </summary>
public DevAVDbDesignTimeUnitOfWork() {
}
IRepository<Customer, long> IDevAVDbUnitOfWork.Customers
{
get { return GetRepository((Customer x) => x.Id); }
}
IRepository<CustomerStore, long> IDevAVDbUnitOfWork.CustomerStores
{
get { return GetRepository((CustomerStore x) => x.Id); }
}
IRepository<Order, long> IDevAVDbUnitOfWork.Orders
{
get { return GetRepository((Order x) => x.Id); }
}
IRepository<Employee, long> IDevAVDbUnitOfWork.Employees
{
get { return GetRepository((Employee x) => x.Id); }
}
IRepository<EmployeeTask, long> IDevAVDbUnitOfWork.Tasks
{
get { return GetRepository((EmployeeTask x) => x.Id); }
}
IRepository<Quote, long> IDevAVDbUnitOfWork.Quotes
{
get { return GetRepository((Quote x) => x.Id); }
}
IRepository<Product, long> IDevAVDbUnitOfWork.Products
{
get { return GetRepository((Product x) => x.Id); }
}
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class EmployeeTaskView : UserControl {
public EmployeeTaskView() {
InitializeComponent();
}
}
}
using System.Collections.Generic;
namespace DevExpress.DevAV.ViewModels {
public interface IFilterTreeModelPageSpecificSettings {
string StaticFiltersTitle { get; }
string CustomFiltersTitle { get; }
FilterInfoList StaticFilters { get; set; }
FilterInfoList CustomFilters { get; set; }
IEnumerable<string> HiddenFilterProperties { get; }
IEnumerable<string> AdditionalFilterProperties { get; }
void SaveSettings();
}
}
using System;
using System.Windows.Controls;
using DevExpress.Data.Filtering.Helpers;
using DevExpress.Xpf.Editors.Filtering;
using DevExpress.Xpf.Editors.Settings;
namespace DevExpress.DevAV.Views {
public partial class CustomFilterView : UserControl {
CustomFilterViewModel ViewModel { get { return (CustomFilterViewModel)DataContext; } }
public CustomFilterView() {
InitializeComponent();
}
}
public class CustomFilterControlColumnsBehavior : FilterControlColumnsBehavior {
protected override FilterColumn CreateFilterColumn(string columnCaption, BaseEditSettings editSettings, Type columnType, string fieldName) {
return new CustomFilterColumn
{
ColumnCaption = columnCaption,
EditSettings = editSettings,
ColumnType = columnType,
FieldName = fieldName
};
}
}
public class CustomFilterColumn : FilterColumn {
public override bool IsValidClause(ClauseType clause) {
return base.IsValidClause(clause) && !Equals(clause, ClauseType.Like) && !Equals(clause, ClauseType.NotLike);
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.DevAVDbView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxn="http://schemas.devexpress.com/winfx/2008/xaml/navbar"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxnav="http://schemas.devexpress.com/winfx/2008/xaml/navigation"
xmlns:dxnavi="http://schemas.devexpress.com/winfx/2008/xaml/navigation/internal"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxwuii="http://schemas.devexpress.com/winfx/2008/xaml/windowsui/internal"
xmlns:dxwuin="http://schemas.devexpress.com/winfx/2008/xaml/windowsui/navigation"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:pfdata="clr-namespace:System.Windows.Data;assembly=PresentationFramework"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="600" d:DesignWidth="800" UseLayoutRounding="True" dx:ScrollBarExtensions.ScrollBarMode="TouchOverlap" DataContext="{dxmvvm:ViewModelSource viewModel:DevAVDbViewModel}">
<UserControl.Resources>
<dxmvvm:ObjectToObjectConverter x:Key="TileColorConverter">
<dxmvvm:MapItem Source="0" Target="#FF00879C" />
<dxmvvm:MapItem Source="1" Target="#FF404040" />
<dxmvvm:MapItem Source="2" Target="#FFCC6D00" />
<dxmvvm:MapItem Source="3" Target="#FF0073C4" />
<dxmvvm:MapItem Source="4" Target="#FF3E7038" />
</dxmvvm:ObjectToObjectConverter>
</UserControl.Resources>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Initialized" Command="{Binding OnLoadedCommand}" CommandParameter="{Binding DefaultModule}" />
<dxmvvm:CurrentWindowService ClosingCommand="{Binding OnClosingCommand}" />
<dxmvvm:LayoutSerializationService Name="RootLayoutSerializationService" />
<dxmvvm:CurrentWindowSerializationBehavior />
<dxwui:WinUIDialogService x:Name="FilterDialogService" />
</dxmvvm:Interaction.Behaviors>
<dx:BackgroundPanel>
<DockPanel>
<DockPanel.Resources>
<CollectionViewSource x:Key="ItemsSource" Source="{Binding Modules}">
<CollectionViewSource.GroupDescriptions>
<pfdata:PropertyGroupDescription PropertyName="ModuleGroup" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</DockPanel.Resources>
<dxnav:TileBar ItemsSource="{Binding Source={StaticResource ItemsSource}}" DockPanel.Dock="Top" Padding="0,0,0,27" Background="#FFE8E8E8" AlternationCount="5" ShowGroupHeaders="False" SelectedItem="{Binding SelectedModule}">
<dxnav:TileBar.ItemContainerStyle>
<Style TargetType="dxnav:TileBarItem">
<Setter Property="Width" Value="166" />
<Setter Property="AllowGlyphTheming" Value="True" />
<Setter Property="Content" Value="{Binding ModuleTitle}" />
<Setter Property="TileGlyph" Value="pack://application:,,,/DevExpress.Images.v16.2;component/GrayScaleImages/Miscellaneous/Cube_16x16.png" />
<Setter Property="Background" Value="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}, Converter={StaticResource TileColorConverter}}" />
<Setter Property="ShowFlyoutButton" Value="{Binding FilterTreeViewModel.CustomFilters.Count, Converter={dxmvvm:CriteriaOperatorConverter Expression=This>0}}" />
<Setter Property="FlyoutContent" Value="{Binding}" />
<Setter Property="FlyoutContentTemplate">
<Setter.Value>
<DataTemplate>
<dxnav:TileBar ItemsSource="{Binding FilterTreeViewModel.CustomFilters}" SelectedItem="{Binding FilterTreeViewModel.SelectedItem}">
<dxnav:TileBar.ItemContainerStyle>
<Style TargetType="dxnav:TileBarItem">
<Setter Property="Height" Value="40" />
<Setter Property="Content" Value="{Binding Name}" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="12" />
</Style>
</dxnav:TileBar.ItemContainerStyle>
<dxnav:TileBar.GroupHeaderStyle>
<Style TargetType="dxnavi:TileBarGroupHeader">
<Setter Property="Foreground" Value="White" />
</Style>
</dxnav:TileBar.GroupHeaderStyle>
</dxnav:TileBar>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</dxnav:TileBar.ItemContainerStyle>
<dxnav:TileBar.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name, Converter={dxmvvm:FormatStringConverter OutStringCaseFormat=Upper}}" Margin="9,28,0,5" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<dxnavi:TileBarItemsPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</dxnav:TileBar.GroupStyle>
</dxnav:TileBar>
<dxwui:NavigationFrame AnimationType="SlideHorizontal">
<dxmvvm:Interaction.Behaviors>
<dxwuin:FrameDocumentUIService>
<dxwuin:FrameDocumentUIService.PageAdornerControlStyle>
<Style TargetType="dxwui:PageAdornerControl">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="18" Margin="5,0,0,0" />
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dxwui:PageAdornerControl">
<Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Margin="{TemplateBinding Padding}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<dxwuii:NavigationHeaderControl Margin="20,10,10,8" VerticalAlignment="Center" x:Name="PART_NavigationHeader" Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" BackCommand="{TemplateBinding BackCommand}" ShowBackButton="{TemplateBinding ShowBackButton}" />
<ContentPresenter Grid.Row="1" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</dxwuin:FrameDocumentUIService.PageAdornerControlStyle>
</dxwuin:FrameDocumentUIService>
</dxmvvm:Interaction.Behaviors>
</dxwui:NavigationFrame>
</DockPanel>
</dx:BackgroundPanel>
</UserControl>
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataAnnotations;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using DevExpress.Mvvm.ViewModel;
using DevExpress.Mvvm.DataModel;
namespace DevExpress.DevAV.Common {
/// <summary>
/// The base class for POCO view models exposing a read-only collection of entities of a given type.
/// This is a partial class that provides the extension point to add custom properties, commands and override methods without modifying the auto-generated code.
/// </summary>
/// <typeparam name="TEntity">An entity type.</typeparam>
/// <typeparam name="TUnitOfWork">A unit of work type.</typeparam>
public partial class ReadOnlyCollectionViewModel<TEntity, TUnitOfWork> : ReadOnlyCollectionViewModel<TEntity, TEntity, TUnitOfWork>
where TEntity : class
where TUnitOfWork : IUnitOfWork {
/// <summary>
/// Creates a new instance of ReadOnlyCollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns a repository representing entities of the given type.</param>
/// <param name="projection">An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data.</param>
public static ReadOnlyCollectionViewModel<TEntity, TUnitOfWork> CreateReadOnlyCollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IReadOnlyRepository<TEntity>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TEntity>> projection = null,
UnitOfWorkPolicy unitOfWorkPolicy = UnitOfWorkPolicy.Individual) {
return ViewModelSource.Create(() => new ReadOnlyCollectionViewModel<TEntity, TUnitOfWork>(unitOfWorkFactory, getRepositoryFunc, projection, unitOfWorkPolicy));
}
/// <summary>
/// Initializes a new instance of the ReadOnlyCollectionViewModel class.
/// This constructor is declared protected to avoid an undesired instantiation of the PeekCollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns a repository representing entities of the given type.</param>
/// <param name="projection">An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data.</param>
protected ReadOnlyCollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IReadOnlyRepository<TEntity>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TEntity>> projection = null,
UnitOfWorkPolicy unitOfWorkPolicy = UnitOfWorkPolicy.Individual)
: base(unitOfWorkFactory, getRepositoryFunc, projection, unitOfWorkPolicy) {
}
}
/// <summary>
/// The base class for POCO view models exposing a read-only collection of entities of a given type.
/// This is a partial class that provides the extension point to add custom properties, commands and override methods without modifying the auto-generated code.
/// </summary>
/// <typeparam name="TEntity">A repository entity type.</typeparam>
/// <typeparam name="TProjection">A projection entity type.</typeparam>
/// <typeparam name="TUnitOfWork">A unit of work type.</typeparam>
public partial class ReadOnlyCollectionViewModel<TEntity, TProjection, TUnitOfWork> : ReadOnlyCollectionViewModelBase<TEntity, TProjection, TUnitOfWork>
where TEntity : class
where TProjection : class
where TUnitOfWork : IUnitOfWork {
/// <summary>
/// Creates a new instance of ReadOnlyCollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns the repository representing entities of a given type.</param>
/// <param name="projection">A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.</param>
public static ReadOnlyCollectionViewModel<TEntity, TProjection, TUnitOfWork> CreateReadOnlyProjectionCollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IReadOnlyRepository<TEntity>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TProjection>> projection,
UnitOfWorkPolicy unitOfWorkPolicy = UnitOfWorkPolicy.Individual) {
return ViewModelSource.Create(() => new ReadOnlyCollectionViewModel<TEntity, TProjection, TUnitOfWork>(unitOfWorkFactory, getRepositoryFunc, projection, unitOfWorkPolicy));
}
/// <summary>
/// Initializes a new instance of the ReadOnlyCollectionViewModel class.
/// This constructor is declared protected to avoid an undesired instantiation of the PeekCollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
/// <param name="getRepositoryFunc">A function that returns the repository representing entities of a given type.</param>
/// <param name="projection">A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.</param>
protected ReadOnlyCollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IReadOnlyRepository<TEntity>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TProjection>> projection,
UnitOfWorkPolicy unitOfWorkPolicy = UnitOfWorkPolicy.Individual)
: base(unitOfWorkFactory, getRepositoryFunc, projection, unitOfWorkPolicy) {
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace DevExpress.DevAV {
public class Order : DatabaseObject {
public Order() {
}
public long InvoiceNumber { get; set; }
public virtual Customer Customer { get; set; }
public long? CustomerId { get; set; }
public virtual CustomerStore Store { get; set; }
public long? StoreId { get; set; }
public string PONumber { get; set; }
public virtual Employee Employee { get; set; }
public long? EmployeeId { get; set; }
public DateTime OrderDate { get; set; }
[DataType(DataType.Currency)]
public decimal SaleAmount { get; set; }
[DataType(DataType.Currency)]
public decimal ShippingAmount { get; set; }
[DataType(DataType.Currency)]
public decimal TotalAmount { get; set; }
public DateTime ShipDate { get; set; }
public string OrderTerms { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExpress.DevAV {
public class CustomerInfo {
public long Id { get; set; }
public string Name { get; set; }
public string AddressLine { get; set; }
public string AddressCity { get; set; }
public StateEnum AddressState { get; set; }
public string AddressZipCode { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public decimal? TotalSales { get; set; }
public IEnumerable<decimal> MonthlySales { get; set; }
Lazy<IEnumerable<CustomerStore>> customerStores;
public IEnumerable<CustomerStore> CustomerStores { get { return customerStores.Value; } }
public void SetDeferredStores(Func<IEnumerable<CustomerStore>> getStores) {
this.customerStores = new Lazy<IEnumerable<CustomerStore>>(getStores);
}
}
}
using DevExpress.DevAV;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.DataModel.EF6;
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExpress.DevAV.DevAVDbDataModel {
/// <summary>
/// A DevAVDbUnitOfWork instance that represents the run-time implementation of the IDevAVDbUnitOfWork interface.
/// </summary>
public class DevAVDbUnitOfWork : DbUnitOfWork<DevAVDb>, IDevAVDbUnitOfWork {
public DevAVDbUnitOfWork(Func<DevAVDb> contextFactory)
: base(contextFactory) {
}
IRepository<Customer, long> IDevAVDbUnitOfWork.Customers
{
get { return GetRepository(x => x.Set<Customer>(), (Customer x) => x.Id); }
}
IRepository<CustomerStore, long> IDevAVDbUnitOfWork.CustomerStores
{
get { return GetRepository(x => x.Set<CustomerStore>(), (CustomerStore x) => x.Id); }
}
IRepository<Order, long> IDevAVDbUnitOfWork.Orders
{
get { return GetRepository(x => x.Set<Order>(), (Order x) => x.Id); }
}
IRepository<Employee, long> IDevAVDbUnitOfWork.Employees
{
get { return GetRepository(x => x.Set<Employee>(), (Employee x) => x.Id); }
}
IRepository<EmployeeTask, long> IDevAVDbUnitOfWork.Tasks
{
get { return GetRepository(x => x.Set<EmployeeTask>(), (EmployeeTask x) => x.Id); }
}
IRepository<Quote, long> IDevAVDbUnitOfWork.Quotes
{
get { return GetRepository(x => x.Set<Quote>(), (Quote x) => x.Id); }
}
IRepository<Product, long> IDevAVDbUnitOfWork.Products
{
get { return GetRepository(x => x.Set<Product>(), (Product x) => x.Id); }
}
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class ProductCollectionView : UserControl {
public ProductCollectionView() {
InitializeComponent();
}
}
}
using DevExpress.DevAV;
using DevExpress.Mvvm.Native;
using DevExpress.Xpo;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Collections.ObjectModel;
using DevExpress.Internal;
namespace DevExpress.DevAV.Generator {
public class DatabaseGenerator {
class Picture {
public byte[] Data { get; set; }
}
SqlConnection sqlConnection;
List<Picture> malePictures;
List<Picture> femalePictures;
List<Picture> currentMalePictures;
List<Picture> currentFemalePictures;
public void Init() {
RaiseProgress("Loading Photos...");
string dbPath = Path.Combine(Environment.CurrentDirectory, @"..\..\Data\Generator\DevAV_source.mdf");
string connectionString = DbEngineDetector.PatchConnectionString(string.Format("data source=(localdb)\\mssqllocaldb;Integrated Security=true;database=DevAV_source;AttachDbFileName={0}", dbPath));
sqlConnection = new SqlConnection(connectionString);
sqlConnection.Open();
}
void RaiseProgress(string p) {
Console.WriteLine(p);
}
public void Seed(DevAVDb context) {
Init();
string connectionString = context.Database.Connection.ConnectionString;
var allResources = typeof(DatabaseGenerator).Assembly.GetManifestResourceNames();
malePictures = allResources.Where(r => r.Contains("MalePhotos")).Select(name => new Picture { Data = ReadEmbeddedResource(name) }).ToList();
femalePictures = allResources.Where(r => r.Contains("FemalePhotos")).Select(name => new Picture { Data = ReadEmbeddedResource(name) }).ToList();
ResetPictures();
context.SaveChanges();
context.SaveChanges();
var crests = CreateCrests();
context.SaveChanges();
var stateEnums = CreateStateEnums();
context.SaveChanges();
var employees = CreateEmployees(stateEnums);
context.Employees.AddRange(employees.Values);
FixEmployeeStatus(employees.Values.ToList());
context.SaveChanges();
var products = CreateProducts(employees);
context.Products.AddRange(products.Values);
context.SaveChanges();
var customers = CreateCustomers(stateEnums);
PatchCustomers(customers.Values.ToList());
context.Customers.AddRange(customers.Values);
context.SaveChanges();
var customerStores = CreateCustomerStores(stateEnums, crests, customers);
context.CustomerStores.AddRange(customerStores.Values);
context.SaveChanges();
currentMalePictures = malePictures.ToList();
currentFemalePictures = femalePictures.ToList();
var tasks = CreateTasks(employees/*, customerEmployees*/);
context.Tasks.AddRange(tasks.Values);
context.SaveChanges();
context.SaveChanges();
var orders = CreateOrders(employees, customers, customerStores);
context.Orders.AddRange(orders.Values);
context.SaveChanges();
context.SaveChanges();
context.SaveChanges();
context.SaveChanges();
context.SaveChanges();
context.SaveChanges();
RaiseProgress("Updating locations...");
context.SaveChanges();
var newOrders = new List<Order>();
DuplicateOrders(context, customers, customerStores, orders.Values.ToList(), connectionString, newOrders);
CreateFakeQuotes(context, connectionString, newOrders);
DropMigrationHistory(context);
}
void DropMigrationHistory(DevAVDb context) {
using(var command = context.Database.Connection.CreateCommand()) {
context.Database.Connection.Open();
command.CommandText = "drop table __MigrationHistory";
command.ExecuteNonQuery();
}
}
void ResetPictures() {
currentMalePictures = malePictures.ToList();
currentFemalePictures = femalePictures.ToList();
}
void FixEmployeeStatus(List<Employee> employees) {
var salaried = employees.Where(e => e.Status == EmployeeStatus.Salaried).ToList();
salaried[4].Status = EmployeeStatus.Contract;
salaried[5].Status = EmployeeStatus.Contract;
salaried[6].Status = EmployeeStatus.Contract;
salaried[7].Status = EmployeeStatus.OnLeave;
salaried[8].Status = EmployeeStatus.OnLeave;
}
void PatchCustomers(List<Customer> customers) {
Customer first = customers.First(c => c.AnnualRevenue > 0);
Random seed = new Random(13);
decimal multiplier = 5000000000m;
var revenues = Enumerable.Range(0, 12).Select(_ => seed.Next(2, 10) * multiplier)
.Concat(Enumerable.Range(12, 7).Select(_ => seed.Next(11, 100) * multiplier));
customers.Except(new[] { first }).Zip(revenues, (c, r) => c.AnnualRevenue = r).ToArray();
customers.ToList().ForEach(c =>
{
c.TotalStores = seed.Next(20, 35);
c.TotalEmployees = seed.Next(2, 20) * 1000;
});
}
Quote OrderToQuote(Order order, ref int number/*, List<OrderItem> orderItems, List<QuoteItem> items*/) {
var quote = new Quote
{
Customer = order.Customer,
CustomerStore = order.Store,
Date = order.OrderDate.AddDays(random.Next(-28, -7)),
Employee = order.Employee,
Number = (number += 3).ToString(),
ShippingAmount = order.ShippingAmount,
SubTotal = order.TotalAmount + order.ShippingAmount,
Total = order.TotalAmount
};
return quote;
}
void CreateFakeQuotes(DevAVDb context, string connectionString, /*List<OrderItem> orderItems, */List<Order> allOrders) {
var newQuotes = new List<Quote>();
Random seed = new Random(13);
var percentages = Enum.GetValues(typeof(StateEnum)).Cast<StateEnum>().ToDictionary(s => s, s => seed.NextDouble() / 1.4 + 0.2); // 0.2 .. 0.9
int number = 3000;
int curState = 0;
var stateGroups = allOrders.GroupBy(o => o.Store.State).ToList();
foreach(var stateGroup in stateGroups) {
Stopwatch sw = new Stopwatch();
sw.Start();
StateEnum state = stateGroup.Key;
List<Order> orders = stateGroup.ToList();
var quotes = orders.Select(o =>
{
var quote = OrderToQuote(o, ref number/*, orderItems, items*/);
return quote;
}).ToList();
while(percentages[state] < (double)orders.Count / quotes.Count) {
quotes.Add(OrderToQuote(orders[seed.Next() % orders.Count], ref number/*, orderItems, items*/));
}
RaiseProgress(string.Format("Creating quotes for state {0}/{1} ({2})", ++curState, stateGroups.Count, sw.Elapsed));
UpdateOpportunity(quotes, percentages[state]);
newQuotes.AddRange(quotes);
}
context.Quotes.AddRange(newQuotes);
context.SaveChanges();
context.SaveChanges();
}
void UpdateOpportunity(List<Quote> quotes, double percentage) {
Random seed = new Random(27);
var ps = Enumerable.Range(0, quotes.Count).Select(_ => seed.NextDouble()).ToList();
double p;
int i = 0;
do {
i++;
p = ps.Average();
int idx = seed.Next() % ps.Count;
if(p > percentage)
ps[idx] = Math.Max(ps[idx] - 0.02, 0);
else
ps[idx] = Math.Min(ps[idx] + 0.02, 1);
} while(Math.Abs(p - percentage) > 0.1);
ps = ps.Select(p0 =>
{
if(Math.Abs(p0 - 1) < 0.01)
return seed.NextDouble() / 5.0 + 0.8;
if(p0 < 0.01)
return seed.NextDouble() / 5.0;
return p0;
}).ToList();
quotes.Zip(ps, (q, p1) => q.Opportunity = p1).ToList();
}
T Duplicate<T>(T item) where T : DatabaseObject, new() {
T res = new T();
foreach(var prop in typeof(T).GetProperties().Where(p => p.Name != "Id")) {
prop.SetValue(res, prop.GetValue(item, null), null);
}
return res;
}
void DuplicateOrdersToDate(
ReadOnlyCollection<Order> ordersForFirstCustomer,
List<Order> newOrders
) {
int curInvoiceNumber = ordersForFirstCustomer.Max(o => (int)o.InvoiceNumber) + 3;
int curPONumber = ordersForFirstCustomer.Max(o => int.Parse(o.PONumber)) + 3;
DateTime minDate = ordersForFirstCustomer.Min(o => o.OrderDate);
DateTime maxDate = new DateTime(2014, 12, 31);
TimeSpan span = ordersForFirstCustomer.Max(o => o.OrderDate) - minDate;
int neededCopy = (int)((maxDate.Ticks - minDate.Ticks) / span.Ticks);
for(int i = 1;
i <= neededCopy;
i++) {
foreach(Order protoOrder in ordersForFirstCustomer.Where(o => o.OrderDate + span <= maxDate).ToList()) {
Order dupOrder = Duplicate(protoOrder);
dupOrder.ShipDate = dupOrder.ShipDate.AddTicks(span.Ticks * i);
dupOrder.OrderDate = dupOrder.OrderDate.AddTicks(span.Ticks * i);
dupOrder.InvoiceNumber = curInvoiceNumber;
dupOrder.PONumber = curPONumber.ToString();
newOrders.Add(dupOrder);
curInvoiceNumber += 3;
curPONumber += 3;
}
}
}
void DuplicateOrders(DevAVDb context,
Dictionary<int, Customer> customers,
Dictionary<int, CustomerStore> customerStores,
List<Order> protoOrders,
string connectionString,
List<Order> newOrders) {
RaiseProgress("duplicating orders (years)");
Customer firstCustomer = customers[1];
PreCorrectOrders(context, protoOrders);
protoOrders.ForEach(o =>
{
o.OrderDate += TimeSpan.FromDays(730);
o.ShipDate += TimeSpan.FromDays(730);
});
DuplicateOrdersToDate(protoOrders.AsReadOnly(),
newOrders
);
protoOrders.AddRange(newOrders);
int curInvoiceNumber = protoOrders.Max(o => (int)o.InvoiceNumber) + 3;
int curPONumber = protoOrders.Max(o => int.Parse(o.PONumber)) + 3;
RaiseProgress("duplicating orders (customers)");
int customersDone = 0;
List<CustomerStore> firstCustomerStores = customerStores.Values.Where(s => s.Customer.Id == firstCustomer.Id).ToList();
foreach(Customer customer in customers.Values.Except(new[] { firstCustomer })) {
List<CustomerStore> stores = customerStores.Values.Where(s => s.Customer.Id == customer.Id).ToList();
Debug.Assert(stores.Count == firstCustomerStores.Count);
var storeMap = new Dictionary<CustomerStore, CustomerStore>();
for(int i = 0;
i < stores.Count;
++i) {
storeMap[firstCustomerStores[i]] = stores[i];
}
foreach(Order order in protoOrders) {
Order dupOrder = Duplicate(order);
dupOrder.Customer = customer;
dupOrder.Store = storeMap[order.Store];
dupOrder.InvoiceNumber = curInvoiceNumber;
dupOrder.PONumber = curPONumber.ToString();
newOrders.Add(dupOrder);
curInvoiceNumber += 3;
curPONumber += 3;
}
RaiseProgress(string.Format("done {0}/{1}", ++customersDone, customers.Values.Count() - 1));
}
context.Orders.AddRange(newOrders);
context.SaveChanges();
context.SaveChanges();
PostCorrectOrders(context);
}
void PostCorrectOrders(DevAVDb context) {
RaiseProgress("PostCorrectOrders");
var random = new Random();
Dictionary<Customer, Tuple<int, bool>> correction = CalculateCorrectionsForOrdersAndOrderItems(context, random);
foreach(var order in context.Orders) {
CorrectDates(random, order);
CorrectOrdersAndOrderItems(context, random, correction, order);
}
context.SaveChanges();
}
static void CorrectOrdersAndOrderItems(DevAVDb context, Random random, Dictionary<Customer, Tuple<int, bool>> correction, Order order) {
if(order.OrderDate.Year != correction[order.Customer].Item1)
return;
bool isNegativeFactor = correction[order.Customer].Item2;
int factor = random.Next(1, 4);
if(isNegativeFactor)
factor *= -1;
order.SaleAmount = 1000; //orderItems.Sum(oi => oi.Total);
order.TotalAmount = order.SaleAmount + order.ShippingAmount;
}
static Dictionary<Customer, Tuple<int, bool>> CalculateCorrectionsForOrdersAndOrderItems(DevAVDb context, Random random) {
Dictionary<Customer, Tuple<int, bool>> correction = new Dictionary<Customer, Tuple<int, bool>>();
int minYear = context.Orders.Min(o => o.OrderDate.Year);
int maxYear = context.Orders.Max(o => o.OrderDate.Year);
var customers = context.Customers.ToList();
for(int i = 0;
i < customers.Count;
i++) {
int year = random.Next(minYear, maxYear + 1);
correction[customers[i]] = new Tuple<int, bool>(year, random.Next(2) == 0);
}
return correction;
}
static void CorrectDates(Random random, Order order) {
var correctSpan = TimeSpan.FromDays(random.Next(0, 6));
order.OrderDate = order.OrderDate + correctSpan;
order.ShipDate = order.ShipDate + correctSpan;
}
void PreCorrectOrders(DevAVDb context, List<Order> orders) {
CorrectSpacesInOrders(orders);
}
static void CorrectSpacesInOrders(List<Order> orders) {
DateTime lastDate = orders[0].OrderDate;
TimeSpan maxSpan = new TimeSpan(7, 0, 0, 0);
var random = new Random();
for(int i = 1;
i < orders.Count;
i++) {
var spanForLast = orders[i].OrderDate - lastDate;
if(spanForLast > maxSpan) {
var correctionSpan = spanForLast - maxSpan + TimeSpan.FromDays(random.Next(-1, 1));
for(int k = i;
k < orders.Count;
k++) {
orders[k].OrderDate = orders[k].OrderDate - correctionSpan;
orders[k].ShipDate = orders[k].ShipDate - correctionSpan;
}
}
lastDate = orders[i].OrderDate;
}
}
public class Crest : DatabaseObject {
public string CityName { get; set; }
public byte[] SmallImage { get; set; }
public byte[] LargeImage { get; set; }
}
public List<Crest> CreateCrests() {
RaiseProgress("Loading Crests...");
var map = new Dictionary<string, string> {
{ "Los Angeles", "Seal_of_Los_Angeles,_California.svg" },
{ "Anaheim", "Seal_of_Anaheim,_California.svg" },
{ "San Diego", "Seal_Of_San_Diego,_California.svg" },
{ "San Jose", "Seal_of_San_Jose,_California" },
{ "Las Vegas", "Las_Vegas_seal.svg" },
{ "Reno", "Nevada-StateSeal.svg" },
{ "Denver", "DenverCOseal" },
{ "Casper", "Seal_of_Wyoming.svg" },
{ "Salt Lake City", "Seal_of_Utah.svg" },
{ "Phoenix", "Arizona-StateSeal.svg" },
{ "Seattle", "Corporate_seal_of_the_City_of_Seattle" },
{ "Spokane", "Seal_of_Washington.svg" },
{ "Portland", "Seal_of_Portland_OR" },
{ "Eugene", "Seal_of_Oregon.svg" },
{ "Sacramento", "Seal_of_California.svg" },
{ "Boise", "Seal_of_Idaho.svg" },
{ "Tucson", "Flag_of_Tucson,_Arizona" },
{ "Colorado Springs", "Seal_of_Colorado.svg" },
{ "Albuquerque", "NewMexico-StateSeal.svg" },
{ "Vancouver", "Vancouver-wa-city-logo2" },
};
return map.Select(p =>
new Crest
{
CityName = p.Key,
SmallImage = ReadResource("/Data/Generator/Seals/" + p.Value + ".small.png"),
LargeImage = ReadResource("/Data/Generator/Seals/" + p.Value + ".large.png")
}
).ToList();
}
List<Tuple<string, byte[]>> GetResources(string part1, string part2) {
var allResources = typeof(DatabaseGenerator).Assembly.GetManifestResourceNames();
return allResources.Where(r => r.Contains(part1) && r.Contains(part2)).Select(n => Tuple.Create(n, ReadEmbeddedResource(n))).ToList();
}
Stack<Picture> GetProductImages(string part1, string part2) {
return new Stack<Picture>(GetResources(part1, part2).Select(p => new Picture { Data = p.Item2 }));
}
T TakeAny<T>(IEnumerable<T> list) where T : class {
return list.ElementAt(random.Next() % list.Count());
}
T TakeAnyAndRemove<T>(List<T> list) where T : class {
T item = TakeAny(list);
list.Remove(item);
return item;
}
public Dictionary<int, Order> CreateOrders(
Dictionary<int, Employee> employees,
Dictionary<int, Customer> customers,
Dictionary<int, CustomerStore> customerStores) {
RaiseProgress("Loading Orders...");
return GetRows("Orders", "Order_ID", g => new Order
{
InvoiceNumber = long.Parse(g.As<string>("Order_Invoice_Number")),
Customer = customers[g.AsScalar<int>("Order_Customer_ID")],
Store = customerStores[g.AsScalar<int>("Order_Customer_Location_ID")],
PONumber = g.As<string>("Order_PO_Number"),
Employee = employees[g.AsScalar<int>("Order_Employee_ID")],
OrderDate = g.AsScalar<DateTime>("Order_Date"),
SaleAmount = g.AsScalar<decimal>("Order_Sale_Amount"),
ShippingAmount = g.AsScalar<decimal>("Order_Shipping_Amount"),
TotalAmount = g.AsScalar<decimal>("Order_Total_Amount"),
ShipDate = g.AsScalar<DateTime>("Order_Ship_Date"),
OrderTerms = g.As<string>("Order_Terms")
});
}
public static DateTime GetRandomDateForProductMapView() {
int factor = 0;
switch(random.Next(0, 3)) {
case 0:
factor = 1;
break;
case 1:
factor = 28;
break;
case 2:
factor = 360;
break;
case 3:
factor = 700;
break;
}
TimeSpan daySpan = new TimeSpan(24, 0, 0);
var span = new TimeSpan((long)(daySpan.Ticks * random.NextDouble() * factor));
return DateTime.Now - span;
}
static string FixAddress(string address) {
var split = address.Split('\n');
if(split.Length > 1)
return split.Last();
return address;
}
static string FixCity(string city) {
return city.Replace("Tuscon", "Tucson")
.Replace("Colorando", "Colorado")
.Replace("Alburquerque", "Albuquerque")
.Replace("Vacouver", "Vancouver");
}
public Dictionary<int, CustomerStore> CreateCustomerStores(
Dictionary<int, StateEnum> states,
List<Crest> crests,
Dictionary<int, Customer> customers) {
return GetRows("Customer_Store_Locations", "Customer_Store_ID", g =>
{
var addressCity = FixCity(g.As<string>("Customer_Store_City"));
return new CustomerStore
{
AddressLine = FixAddress(g.As<string>("Customer_Store_Address")),
AddressCity = addressCity,
AddressState = states[g.AsScalar<int>("Customer_Store_State")],
AddressZipCode = g.As<string>("Customer_Store_Zipcode"),
Phone = FixPhone(g.As<string>("Customer_Store_Phone")),
Fax = FixPhone(g.As<string>("Customer_Store_Fax")),
TotalEmployees = g.AsScalar<int>("Customer_Store_Total_Employees"),
SquereFootage = g.AsScalar<int>("Customer_Store_Square_Footage"),
AnnualSales = g.AsScalar<decimal>("Customer_Store_Annual_Sales"),
CrestLarge = crests.First(c => c.CityName == addressCity).LargeImage,
CrestSmall = crests.First(c => c.CityName == addressCity).SmallImage,
Customer = customers[g.AsScalar<int>("Customer_ID")],
Location = g.As<string>("Customer_Store_Location")
};
});
}
public Dictionary<int, StateEnum> CreateStateEnums() {
return GetRows("States", "Sate_ID", g => g.AsEnum<StateEnum>("State_Short"));
}
public Dictionary<int, Customer> CreateCustomers(Dictionary<int, StateEnum> states) {
RaiseProgress("Loading Customers...");
var logos = GetResources("CustomerLogos", "").Select(l => l.Item2).ToList();
return GetRows("Customers", "Customer_ID", g => new Customer
{
Name = g.As<string>("Customer_Name"),
AddressLine = FixAddress(g.As<string>("Customer_Billing_Address")),
AddressCity = FixCity(g.As<string>("Customer_Billing_City")),
AddressState = states[g.AsScalar<int>("Customer_Billing_State")],
AddressZipCode = g.As<string>("Customer_Billing_Zipcode"),
Phone = g.As<string>("Customer_Phone"),
Fax = g.As<string>("Customer_Fax"),
Website = g.As<string>("Customer_Website"),
AnnualRevenue = g.AsScalar<decimal>("Customer_Annual_Revenue"),
TotalStores = g.AsScalar<int>("Customer_Total_Stores"),
TotalEmployees = g.AsScalar<int>("Customer_Total_Employees"),
Status = RowGetter.ParseEnum<CustomerStatus>(g.As<string>("Customer_Status") ?? "Active"),
Logo = TakeAnyAndRemove(logos),
});
}
DateTime? ParseDateTime(string str) {
if(str == null)
return null;
DateTime res = DateTime.Parse(str, CultureInfo.InvariantCulture);
if(res.Year == 203)
res = new DateTime(2013, res.Month, res.Day, res.Hour, res.Minute, res.Second);
return res;
}
string Unescape(string str, bool keepReturns) {
string noTags = new Regex("<.*?>").Replace(str, "");
string noEscapes = noTags.Replace("&", "&").Replace(" ", " ");
if(keepReturns)
return noEscapes;
var split = noEscapes.Split('\n')
.Where(l => !string.IsNullOrWhiteSpace(l));
if(split.Any())
return split.Aggregate((l, r) => l + "\n" + r);
return "";
}
public Dictionary<int, EmployeeTask> CreateTasks(
Dictionary<int, Employee> employees
) {
RaiseProgress("Loading Tasks...");
return GetRows("Tasks", "Task_ID", g =>
{
DateTime? date = ParseDateTime(g.As<string>("Task_Reminder_Date"));
DateTime? time = ParseDateTime(g.As<string>("Task_Reminder_Time"));
int? customerEmployeeId = g.AsNullable<int>("Task_Customer_Employee_ID");
return new EmployeeTask
{
AssignedEmployee = employees[g.AsScalar<int>("Task_Assigned_Employee_ID")],
Subject = g.As<string>("Task_Subject"),
Description = Unescape(g.As<string>("Task_Description"), false),
StartDate = ParseDateTime(g.As<string>("Task_Start_Date")),
DueDate = ParseDateTime(g.As<string>("Task_Due_Date")),
Status = g.AsEnum<EmployeeTaskStatus>("Task_Status"),
Priority = g.AsEnum<EmployeeTaskPriority>("Task_Priority"),
Completion = g.AsNullable<int>("Task_Completion") ?? 0,
Reminder = g.AsScalar<bool>("Task_Reminder"),
ReminderDateTime = (date == null || time == null) ? (DateTime?)null :
new DateTime(date.Value.Year, date.Value.Month, date.Value.Day, time.Value.Hour, time.Value.Minute, time.Value.Second)
};
});
}
static Random random = new Random();
public Dictionary<int, Employee> CreateEmployees(
Dictionary<int, StateEnum> states
//, Dictionary<int, Probation> probations
) {
RaiseProgress("Loading Employees...");
return GetRows("Employees", "Employee_ID", g =>
{
var profile = Unescape(g.As<string>("Employee_Personal_Profile") ?? "", true);
var id = g.AsScalar<int>("Employee_ID");
if(id == 48) { // Brad Farkus
profile = "Brad is on probation for excessive tardiness. We hope to see him back at his desk shortly.\n\nPlease remember tardiness is not something we tolerate.";
}
if(id == 22) { // Amelia Harper
profile = "Amelia is on probation for failure to follow-up on tasks. We hope to see her back at her desk shortly.\n\nPlease remember negligence of assigned tasks is not something we tolerate.";
}
var prefix = ParsePrefix(g.As<string>("Employee_Prefix"));
string fullName = g.As<string>("Employee_Full_Name");
Employee res = new Employee
{
FirstName = g.As<string>("Employee_First_Name"),
LastName = g.As<string>("Employee_Last_Name"),
Prefix = prefix,
Title = g.As<string>("Employee_Title"),
Picture = GetImageForPrefix(prefix, fullName).With(x => x.Data),
AddressLine = FixAddress(g.As<string>("Employee_Address")),
AddressCity = FixCity(g.As<string>("Employee_City")),
AddressState = states[g.AsScalar<int>("Employee_State_ID")],
AddressZipCode = g.AsScalar<int>("Employee_Zipcode").ToString("d5"),
Email = g.As<string>("Employee_Email"),
Skype = g.As<string>("Employee_Skype"),
MobilePhone = FixPhone(g.As<string>("Employee_Mobile_Phone")),
HomePhone = FixPhone(g.As<string>("Employee_Home_Phone")),
BirthDate = g.AsScalar<DateTime>("Employee_Birth_Date"),
HireDate = g.AsScalar<DateTime>("Employee_Hire_Date"),
Department = (EmployeeDepartment)g.AsScalar<int>("Employee_Department_ID"),
Status = g.AsEnum<EmployeeStatus>("Employee_Status"),
PersonalProfile = profile,
Order = g.AsScalar<int>("Employee_ID")
};
return res;
});
}
string FixPhone(string num) {
num = num.Replace(" ", "").Replace(")", "").Replace("(", "").Replace("-", "");
return string.Format("({0}) {1}-{2}", num.Substring(0, 3), num.Substring(3, 3), num.Substring(6, 4));
}
public Dictionary<int, Product> CreateProducts(Dictionary<int, Employee> employees) {
RaiseProgress("Loading Products...");
return GetRows("Products", "Product_ID", g => new Product
{
Name = g.As<string>("Product_Name"),
Description = @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
ProductionStart = g.AsScalar<DateTime>("Product_Production_Start"),
Available = g.AsScalar<bool>("Product_Available"),
Image = ReadResource("/Data/Generator/Products/ProductImage.png"),
Support = employees[g.AsScalar<int>("Product_Support_ID")],
Engineer = employees[g.AsScalar<int>("Product_Engineer_ID")],
CurrentInventory = g.AsNullable<int>("Product_Current_Inventory"),
Backorder = g.AsScalar<int>("Product_Backorder"),
Manufacturing = g.AsScalar<int>("Product_Manufacturing"),
Barcode = g.As<byte[]>("Product_Barcode"),
Cost = g.AsScalar<decimal>("Product_Cost"),
SalePrice = g.AsScalar<decimal>("Product_Sale_Price"),
RetailPrice = g.AsScalar<decimal>("Product_Retail_Price"),
ConsumerRating = g.AsScalar<double>("Product_Consumer_Rating"),
Category = GetCategory(g.As<string>("Product_Category"))
});
}
class RowGetter {
DataRow row;
public RowGetter(DataRow row) {
this.row = row;
}
public T As<T>(string name) where T : class {
var val = row[name];
if(val is DBNull)
return null;
if(typeof(T) == typeof(string))
return val.ToString() as T;
return (T)val;
}
public T? AsNullable<T>(string name) where T : struct {
var val = row[name];
if(val is DBNull)
return null;
return (T)val;
}
public T AsScalar<T>(string name) {
return (T)row[name];
}
public T AsEnum<T>(string name) {
return ParseEnum<T>((string)row[name]);
}
public static T ParseEnum<T>(string str) {
return (T)Enum.Parse(typeof(T), str.Replace(" ", ""));
}
}
Dictionary<int, T> GetRows<T>(string tableName, string idName, Func<RowGetter, T> selector) {
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.TableMappings.Add("Table", tableName);
adapter.SelectCommand = new SqlCommand(string.Format("SELECT * FROM dbo.{0};", tableName), sqlConnection) { CommandType = CommandType.Text };
DataSet dataSet = new DataSet(tableName);
adapter.Fill(dataSet);
return dataSet.Tables[tableName].Rows.Cast<DataRow>()
.ToDictionary(row => (int)row[idName], row => selector(new RowGetter(row)));
}
static string GetNoteText(int i) {
switch(i) {
case 0:
return "This is an RTF note for Jimmy. Jimmy is one of those great people. He is understanding.";
case 1:
return "Jimmy's birthday today. He turns 25. Don't forget to join us for the celebration.";
default:
return "random note " + i;
}
}
Picture GetImageForPrefix(PersonPrefix prefix, string fullName) {
Picture res = null;
if(fullName == "Samantha Bright") {
prefix = PersonPrefix.Ms;
} else if(fullName == "Ed Holmes") {
prefix = PersonPrefix.Mr;
} else if(fullName == "Ken Samuelson") {
prefix = PersonPrefix.Mr;
} else if(fullName == "Billy Zimmer") {
return null;
}
if(prefix == PersonPrefix.Mr) {
res = currentMalePictures[random.Next(0, currentMalePictures.Count - 1)];
currentMalePictures.Remove(res);
} else if(prefix == PersonPrefix.Ms || prefix == PersonPrefix.Mrs || prefix == PersonPrefix.Miss) {
res = currentFemalePictures[random.Next(0, currentFemalePictures.Count - 1)];
currentFemalePictures.Remove(res);
}
return res; // Dr
}
PersonPrefix ParsePrefix(string p) {
switch(p) {
default:
return PersonPrefix.Miss;
case "Dr.":
return PersonPrefix.Dr;
case "Miss":
return PersonPrefix.Miss;
case "Mr.":
return PersonPrefix.Mr;
case "Mrs.":
return PersonPrefix.Mrs;
case "Ms.":
return PersonPrefix.Ms;
}
}
byte[] ReadResource(string relativePath) {
relativePath = "pack://application:,,,/" + Assembly.GetExecutingAssembly().GetName().Name + ";component" + relativePath;
using(BinaryReader binaryReader = new BinaryReader(Application.GetResourceStream(new Uri(relativePath)).Stream)) {
return binaryReader.ReadBytes((int)binaryReader.BaseStream.Length);
}
}
byte[] ReadEmbeddedResource(string name) {
name = name.Replace("%20", " ");
using(BinaryReader binaryReader = new BinaryReader(typeof(DatabaseGenerator).Assembly.GetManifestResourceStream(name))) {
return binaryReader.ReadBytes((int)binaryReader.BaseStream.Length);
}
}
ProductCategory GetCategory(string value) {
ProductCategory res;
if(Enum.TryParse(value, out res))
return res;
return ProductCategory.VideoPlayers;
}
}
}
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
namespace DevExpress.DevAV {
public class DevAVDb : DbContext {
public DevAVDb() {
}
public DbSet<Employee> Employees { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Quote> Quotes { get; set; }
public DbSet<EmployeeTask> Tasks { get; set; }
public DbSet<CustomerStore> CustomerStores { get; set; }
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class CustomerView : UserControl {
public CustomerView() {
InitializeComponent();
}
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization">
<!--#region Commands-->
<Style x:Key="CollectionView.Command.Base" TargetType="dxwui:AppBarButton">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="AllowGlyphTheming" Value="True" />
<Setter Property="GlyphStretch" Value="None" />
<Setter Property="IsEllipseEnabled" Value="False" />
</Style>
<Style x:Key="CollectionView.Command.New" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_New}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=New_32x32.png}}" />
<Setter Property="Command" Value="{Binding NewCommand}" />
</Style>
<Style x:Key="CollectionView.Command.Edit" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_Edit}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=Edit_32x32.png}}" />
<Setter Property="Command" Value="{Binding EditCommand}" />
<Setter Property="CommandParameter" Value="{Binding SelectedEntity}" />
</Style>
<Style x:Key="CollectionView.Command.Delete" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_Delete}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=Delete_32x32.png}}" />
<Setter Property="Command" Value="{Binding DeleteCommand}" />
<Setter Property="CommandParameter" Value="{Binding SelectedEntity}" />
</Style>
<Style x:Key="CollectionView.Command.Refresh" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_Refresh}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=Refresh_32x32.png}}" />
<Setter Property="Command" Value="{Binding RefreshCommand}" />
</Style>
<Style x:Key="CollectionView.Command.Reports" BasedOn="{StaticResource CollectionView.Command.Base}" TargetType="dxwui:AppBarButton">
<Setter Property="Label" Value="{x:Static localization:ViewResources.Command_Reports}" />
<Setter Property="Glyph" Value="{Binding Source={dx:DXImageGrayscale Image=Print_32x32.png}}" />
</Style>
<!--#endregion Commands-->
<!--#region AppBar-->
<Style x:Key="CollectionView.AppBar" TargetType="dxwui:AppBar">
<Setter Property="HideMode" Value="AlwaysVisible" />
</Style>
<!--#endregion AppBar-->
<!--#region Containers-->
<Style x:Key="CollectionView.RootContainer" TargetType="FrameworkElement">
<Setter Property="dxmvvm:Interaction.BehaviorsTemplate">
<Setter.Value>
<DataTemplate>
<ItemsControl>
<dxmvvm:EventToCommand Event="Loaded" Command="{Binding OnLoadedCommand}" />
<dxmvvm:EventToCommand Event="Unloaded" Command="{Binding OnUnloadedCommand}" />
<dxwui:WinUIMessageBoxService />
<dx:WindowedDocumentUIService YieldToParent="True" />
<dxmvvm:LayoutSerializationService />
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion Containers-->
<!--#region GridControl-->
<Style x:Key="CollectionView.GridControl.Base" TargetType="dxg:GridControl">
<Setter Property="ItemsSource" Value="{Binding Entities}" />
<Setter Property="CurrentItem" Value="{Binding SelectedEntity}" />
<Setter Property="ShowLoadingPanel" Value="{Binding IsLoading}" />
<Setter Property="Margin" Value="50,16,42,2" />
</Style>
<Style x:Key="CollectionView.GridControl.Editable" BasedOn="{StaticResource CollectionView.GridControl.Base}" TargetType="dxg:GridControl">
<Setter Property="dxmvvm:Interaction.BehaviorsTemplate">
<Setter.Value>
<DataTemplate>
<ItemsControl>
<dxmvvm:EventToCommand EventName="MouseDoubleClick" Command="{Binding EditCommand}" PassEventArgsToCommand="True" MarkRoutedEventsAsHandled="True">
<dxmvvm:EventToCommand.EventArgsConverter>
<dx:EventArgsToDataRowConverter />
</dxmvvm:EventToCommand.EventArgsConverter>
</dxmvvm:EventToCommand>
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CollectionView.GridControl.ReadOnly" BasedOn="{StaticResource CollectionView.GridControl.Base}" TargetType="dxg:GridControl" />
<Style x:Key="CollectionView.TableView" TargetType="dxg:TableView">
<Setter Property="AllowEditing" Value="False" />
<Setter Property="ShowFixedTotalSummary" Value="True" />
<Setter Property="AllowPerPixelScrolling" Value="True" />
<Setter Property="ShowGroupPanel" Value="False" />
<Setter Property="ShowIndicator" Value="False" />
</Style>
<!--#endregion GridControl-->
</ResourceDictionary>
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the single Employee object view model.
/// </summary>
public partial class EmployeeViewModel : SingleObjectViewModel<Employee, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of EmployeeViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static EmployeeViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new EmployeeViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the EmployeeViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the EmployeeViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected EmployeeViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Employees, x => x.FullName) {
}
/// <summary>
/// The view model that contains a look-up collection of Tasks for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<EmployeeTask> LookUpTasks
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (EmployeeViewModel x) => x.LookUpTasks,
getRepositoryFunc: x => x.Tasks);
}
}
/// <summary>
/// The view model for the EmployeeAssignedTasks detail collection.
/// </summary>
public CollectionViewModelBase<EmployeeTask, EmployeeTask, long, IDevAVDbUnitOfWork> EmployeeAssignedTasksDetails
{
get
{
return GetDetailsCollectionViewModel(
propertyExpression: (EmployeeViewModel x) => x.EmployeeAssignedTasksDetails,
getRepositoryFunc: x => x.Tasks,
foreignKeyExpression: x => x.AssignedEmployeeId,
navigationExpression: x => x.AssignedEmployee);
}
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.OrderCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:OrderCollectionViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/CollectionViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource CollectionView.RootContainer}">
<dxwui:AppBar Style="{StaticResource CollectionView.AppBar}" DockPanel.Dock="Bottom">
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.New}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Edit}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Delete}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Refresh}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Reports}">
<dxmvvm:Interaction.Behaviors>
<dxrudex:ReportManagerBehavior Service="{Binding ElementName=OrderCollectionViewReportService}" ImageType="GrayScaled" />
</dxmvvm:Interaction.Behaviors>
</dxwui:AppBarButton>
</dxwui:AppBar>
<dxg:GridControl Name="gridControl" ItemsSource="{Binding Entities}" SelectedItem="{Binding SelectedEntity}" ShowLoadingPanel="{Binding IsLoading}" Margin="50,16,42,2">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand PassEventArgsToCommand="True" Command="{Binding EditCommand}" EventName="MouseDoubleClick">
<dxmvvm:EventToCommand.EventArgsConverter>
<dx:EventArgsToDataRowConverter />
</dxmvvm:EventToCommand.EventArgsConverter>
</dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<dxg:GridControl.Columns>
<dxg:GridColumn IsSmart="True" FieldName="InvoiceNumber" Header="Invoice" Width="120" FixedWidth="True" />
<dxg:GridColumn IsSmart="True" FieldName="OrderDate" Header="Order Date" Width="100" FixedWidth="True" />
<dxg:GridColumn FieldName="Customer.Name" Header="Name" ReadOnly="True" FixedWidth="False" />
<dxg:GridColumn IsSmart="True" FieldName="Store.AddressCityLine" Header="City Line" ReadOnly="True" FixedWidth="False" />
<dxg:GridColumn IsSmart="True" FieldName="TotalAmount" Header="Total Amount" FixedWidth="True" Width="130" />
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Count" Alignment="Right" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.GroupSummary>
<dxg:GridSummaryItem SummaryType="Count" />
</dxg:GridControl.GroupSummary>
<dxg:GridControl.View>
<dxg:TableView Name="tableView" AllowEditing="False" ShowFixedTotalSummary="True" AllowPerPixelScrolling="True" ShowGroupPanel="False" ShowIndicator="False" AutoWidth="True" />
</dxg:GridControl.View>
</dxg:GridControl>
</DockPanel>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.Localization;
using DevExpress.DevAV.DevAVDbDataModel;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the root POCO view model for the DevAVDb data model.
/// </summary>
public partial class DevAVDbViewModel : DocumentsViewModel<DevAVDbModuleDescription, IDevAVDbUnitOfWork> {
const string MyWorldGroup = "My World";
const string OperationsGroup = "Operations";
INavigationService NavigationService { get { return this.GetService<INavigationService>(); } }
/// <summary>
/// Creates a new instance of DevAVDbViewModel as a POCO view model.
/// </summary>
public static DevAVDbViewModel Create() {
return ViewModelSource.Create(() => new DevAVDbViewModel());
}
static DevAVDbViewModel() {
MetadataLocator.Default = MetadataLocator.Create().AddMetadata<DevAVDbMetadataProvider>();
}
/// <summary>
/// Initializes a new instance of the DevAVDbViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the DevAVDbViewModel type without the POCO proxy factory.
/// </summary>
protected DevAVDbViewModel()
: base(UnitOfWorkSource.GetUnitOfWorkFactory()) {
}
protected override DevAVDbModuleDescription[] CreateModules() {
var modules = new DevAVDbModuleDescription[] {
new DevAVDbModuleDescription("Tasks", "EmployeeTaskCollectionView", MyWorldGroup, FiltersSettings.GetTasksFilterTree(this)),
new DevAVDbModuleDescription("Employees", "EmployeeCollectionView", MyWorldGroup, FiltersSettings.GetEmployeesFilterTree(this)),
new DevAVDbModuleDescription("Products", "ProductCollectionView", OperationsGroup, FiltersSettings.GetProductsFilterTree(this)),
new DevAVDbModuleDescription("Customers", "CustomerCollectionView", OperationsGroup, FiltersSettings.GetCustomersFilterTree(this)),
new DevAVDbModuleDescription("Sales", "OrderCollectionView", OperationsGroup, FiltersSettings.GetSalesFilterTree(this)),
new DevAVDbModuleDescription("Opportunities", "QuoteCollectionView", OperationsGroup, FiltersSettings.GetOpportunitiesFilterTree(this))
};
foreach(var module in modules) {
DevAVDbModuleDescription moduleRef = module;
//_ Action that shows module if is not visible at the moment when filter is selected
module.FilterTreeViewModel.NavigateAction = () => Show(moduleRef);
}
return modules;
}
public override DevAVDbModuleDescription DefaultModule
{
get { return Modules[1]; }
}
protected override void OnActiveModuleChanged(DevAVDbModuleDescription oldModule) {
if(ActiveModule != null) {
NavigationService.ClearNavigationHistory();
}
base.OnActiveModuleChanged(oldModule);
if(ActiveModule != null && ActiveModule.FilterTreeViewModel != null)
ActiveModule.FilterTreeViewModel.SetViewModel(DocumentManagerService.ActiveDocument.Content);
}
}
public partial class DevAVDbModuleDescription : ModuleDescription<DevAVDbModuleDescription> {
public DevAVDbModuleDescription(string title, string documentType, string group, IFilterTreeViewModel filterTreeViewModel = null)
: base(title, documentType, group, null) {
FilterTreeViewModel = filterTreeViewModel;
}
public IFilterTreeViewModel FilterTreeViewModel { get; private set; }
}
}
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the single Customer object view model.
/// </summary>
public partial class CustomerViewModel : SingleObjectViewModel<Customer, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of CustomerViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static CustomerViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new CustomerViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the CustomerViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the CustomerViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected CustomerViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Customers, x => x.Name) {
}
/// <summary>
/// The view model that contains a look-up collection of CustomerStores for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<CustomerStore> LookUpCustomerStores
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (CustomerViewModel x) => x.LookUpCustomerStores,
getRepositoryFunc: x => x.CustomerStores);
}
}
/// <summary>
/// The view model that contains a look-up collection of Orders for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<Order> LookUpOrders
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (CustomerViewModel x) => x.LookUpOrders,
getRepositoryFunc: x => x.Orders);
}
}
/// <summary>
/// The view model that contains a look-up collection of Quotes for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<Quote> LookUpQuotes
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (CustomerViewModel x) => x.LookUpQuotes,
getRepositoryFunc: x => x.Quotes);
}
}
/// <summary>
/// The view model for the CustomerCustomerStores detail collection.
/// </summary>
public CollectionViewModelBase<CustomerStore, CustomerStore, long, IDevAVDbUnitOfWork> CustomerCustomerStoresDetails
{
get
{
return GetDetailsCollectionViewModel(
propertyExpression: (CustomerViewModel x) => x.CustomerCustomerStoresDetails,
getRepositoryFunc: x => x.CustomerStores,
foreignKeyExpression: x => x.CustomerId,
navigationExpression: x => x.Customer);
}
}
/// <summary>
/// The view model for the CustomerOrders detail collection.
/// </summary>
public CollectionViewModelBase<Order, Order, long, IDevAVDbUnitOfWork> CustomerOrdersDetails
{
get
{
return GetDetailsCollectionViewModel(
propertyExpression: (CustomerViewModel x) => x.CustomerOrdersDetails,
getRepositoryFunc: x => x.Orders,
foreignKeyExpression: x => x.CustomerId,
navigationExpression: x => x.Customer);
}
}
/// <summary>
/// The view model for the CustomerQuotes detail collection.
/// </summary>
public CollectionViewModelBase<Quote, Quote, long, IDevAVDbUnitOfWork> CustomerQuotesDetails
{
get
{
return GetDetailsCollectionViewModel(
propertyExpression: (CustomerViewModel x) => x.CustomerQuotesDetails,
getRepositoryFunc: x => x.Quotes,
foreignKeyExpression: x => x.CustomerId,
navigationExpression: x => x.Customer);
}
}
}
}
using DevExpress.Mvvm;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DevExpress.DevAV {
public enum StateEnum {
CA,
AR,
AL,
AK,
AZ,
CO,
CT,
DE,
DC,
FL,
GA,
HI,
ID,
IL,
IN,
IA,
KS,
KY,
LA,
ME,
MD,
MA,
MI,
MN,
MS,
MO,
MT,
NE,
NV,
NH,
NJ,
NM,
NY,
NC,
OH,
OK,
OR,
PA,
RI,
SC,
SD,
TN,
TX,
UT,
VT,
VA,
WA,
WV,
WI,
WY,
ND
}
}
using DevExpress.Mvvm.UI.Interactivity;
using DevExpress.Xpf.Core.Native;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Controls;
namespace DevExpress.DevAV {
public class HorizontalScrollingOnMouseWheelBehavior : Behavior<ListView> {
protected override void OnAttached() {
base.OnAttached();
AssociatedObject.PreviewMouseWheel += OnPreviewMouseWheel;
}
protected override void OnDetaching() {
base.OnDetaching();
AssociatedObject.PreviewMouseWheel -= OnPreviewMouseWheel;
}
void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e) {
var scrollBar = (ScrollBar)LayoutHelper.FindElementByName(AssociatedObject, "PART_HorizontalScrollBar");
if(e.Delta > 0)
ScrollBar.LineLeftCommand.Execute(null, scrollBar);
else if(e.Delta < 0) {
ScrollBar.LineRightCommand.Execute(null, scrollBar);
}
}
}
}
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the single Quote object view model.
/// </summary>
public partial class QuoteViewModel : SingleObjectViewModel<Quote, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of QuoteViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static QuoteViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new QuoteViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the QuoteViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the QuoteViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected QuoteViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Quotes, x => x.Number) {
}
/// <summary>
/// The view model that contains a look-up collection of Customers for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<Customer> LookUpCustomers
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (QuoteViewModel x) => x.LookUpCustomers,
getRepositoryFunc: x => x.Customers);
}
}
/// <summary>
/// The view model that contains a look-up collection of CustomerStores for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<CustomerStore> LookUpCustomerStores
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (QuoteViewModel x) => x.LookUpCustomerStores,
getRepositoryFunc: x => x.CustomerStores);
}
}
/// <summary>
/// The view model that contains a look-up collection of Employees for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<Employee> LookUpEmployees
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (QuoteViewModel x) => x.LookUpEmployees,
getRepositoryFunc: x => x.Employees);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using DevExpress.Xpf.Core;
namespace DevExpress.HybridApp {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : DXWindow {
public MainWindow() {
InitializeComponent();
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.EmployeeTaskCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:EmployeeTaskCollectionViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/CollectionViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource CollectionView.RootContainer}">
<dxwui:AppBar Style="{StaticResource CollectionView.AppBar}" DockPanel.Dock="Bottom">
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.New}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Edit}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Delete}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Refresh}" />
<dxwui:AppBarButton Style="{StaticResource CollectionView.Command.Reports}">
<dxmvvm:Interaction.Behaviors>
<dxrudex:ReportManagerBehavior Service="{Binding ElementName=EmployeeTaskCollectionViewReportService}" ImageType="GrayScaled" />
</dxmvvm:Interaction.Behaviors>
</dxwui:AppBarButton>
</dxwui:AppBar>
<view:StaticFiltersPanel DockPanel.Dock="Left" />
<dxg:GridControl Name="gridControl" ItemsSource="{Binding Entities}" SelectedItem="{Binding SelectedEntity}" ShowLoadingPanel="{Binding IsLoading}" Margin="50,16,42,2">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand PassEventArgsToCommand="True" Command="{Binding EditCommand}" EventName="MouseDoubleClick">
<dxmvvm:EventToCommand.EventArgsConverter>
<dx:EventArgsToDataRowConverter />
</dxmvvm:EventToCommand.EventArgsConverter>
</dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<dxg:GridControl.Columns>
<dxg:GridColumn FieldName="AssignedEmployee.FullName" Header="Assigned To" ReadOnly="True" Width="180" />
<dxg:GridColumn IsSmart="True" FieldName="Subject" Width="355" />
<dxg:GridColumn IsSmart="True" FieldName="Priority" AllowSorting="False" AllowColumnFiltering="False" Width="92" />
<dxg:GridColumn IsSmart="True" FieldName="DueDate" Width="115" />
<dxg:GridColumn IsSmart="True" FieldName="Completion" Header="% Complete" Width="184" MinWidth="80">
<dxg:GridColumn.EditSettings>
<dxe:TextEditSettings MaskUseAsDisplayFormat="True" MaskType="Numeric" Mask="P0" TextWrapping="NoWrap" />
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Count" FieldName="Completion" DisplayFormat="{}TOTAL # OF TASKS: {0}" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.GroupSummary>
<dxg:GridSummaryItem SummaryType="Count" />
</dxg:GridControl.GroupSummary>
<dxg:GridControl.View>
<dxg:TableView Name="tableView" AllowEditing="False" TotalSummaryPosition="Bottom" AllowPerPixelScrolling="True" AutoWidth="True" ShowIndicator="False" ShowGroupPanel="False" ShowSearchPanelMode="Never" NavigationStyle="Row" ShowFilterPanelMode="Never" AllowMoveColumnToDropArea="False">
<dxg:TableView.FormatConditions>
<dxg:DataBarFormatCondition FieldName="Completion" PredefinedFormatName="BlueSolidDataBar" MinValue="0" MaxValue="100" />
<dxg:IconSetFormatCondition FieldName="Priority">
<dx:IconSetFormat ElementThresholdType="Number">
<dx:IconSetElement ThresholdComparisonType="GreaterOrEqual" Threshold="3" Icon="pack://application:,,,/DevExpress.Xpf.Core.v16.2;component/Core/ConditionalFormatting/Images/IconSets/Rating4_1.png" />
<dx:IconSetElement ThresholdComparisonType="GreaterOrEqual" Threshold="2" Icon="pack://application:,,,/DevExpress.Xpf.Core.v16.2;component/Core/ConditionalFormatting/Images/IconSets/Rating4_2.png" />
<dx:IconSetElement ThresholdComparisonType="GreaterOrEqual" Threshold="1" Icon="pack://application:,,,/DevExpress.Xpf.Core.v16.2;component/Core/ConditionalFormatting/Images/IconSets/Rating4_3.png" />
<dx:IconSetElement ThresholdComparisonType="GreaterOrEqual" Threshold="0" Icon="pack://application:,,,/DevExpress.Xpf.Core.v16.2;component/Core/ConditionalFormatting/Images/IconSets/Rating4_4.png" />
</dx:IconSetFormat>
</dxg:IconSetFormatCondition>
<dxg:FormatCondition ApplyToRow="True" Expression="[Subject] = '100'" FieldName="Subject" PredefinedFormatName="StrikethroughText" />
<dxg:FormatCondition ApplyToRow="True" Expression="[Completion] = 100.0m" FieldName="Completion" PredefinedFormatName="StrikethroughText" />
</dxg:TableView.FormatConditions>
</dxg:TableView>
</dxg:GridControl.View>
</dxg:GridControl>
</DockPanel>
</UserControl>
using System;
using DevExpress.Mvvm.POCO;
using System.Collections.Generic;
using DevExpress.Data.Filtering;
namespace DevExpress.DevAV {
public class CustomFilterViewModel {
public static CustomFilterViewModel Create(Type entityType, IEnumerable<string> hiddenProperties, IEnumerable<string> additionalProperties) {
return ViewModelSource.Create(() => new CustomFilterViewModel(entityType, hiddenProperties, additionalProperties));
}
protected CustomFilterViewModel(Type entityType, IEnumerable<string> hiddenProperties, IEnumerable<string> additionalProperties) {
EntityType = entityType;
HiddenProperties = hiddenProperties;
AdditionalProperties = additionalProperties;
}
public Type EntityType { get; private set; }
public IEnumerable<string> HiddenProperties { get; private set; }
public IEnumerable<string> AdditionalProperties { get; private set; }
public virtual bool Save { get; set; }
public virtual CriteriaOperator FilterCriteria { get; set; }
public virtual string FilterName { get; set; }
}
}
using System;
using System.Linq;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the Tasks collection view model.
/// </summary>
public partial class EmployeeTaskCollectionViewModel : CollectionViewModel<EmployeeTask, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of EmployeeTaskCollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static EmployeeTaskCollectionViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new EmployeeTaskCollectionViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the EmployeeTaskCollectionViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the EmployeeTaskCollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected EmployeeTaskCollectionViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Tasks, query => query.OrderByDescending(x => x.DueDate)) {
}
}
}
using DevExpress.DevAV;
using DevExpress.DevAV.Localization;
using DevExpress.Mvvm.DataAnnotations;
namespace DevExpress.DevAV.DevAVDbDataModel {
public class DevAVDbMetadataProvider {
public static void BuildMetadata(MetadataBuilder<Customer> builder) {
builder.DisplayName(DevAVDbResources.Customer);
builder.Property(x => x.Name).DisplayName(DevAVDbResources.Customer_Name);
builder.Property(x => x.AddressState).DisplayName(DevAVDbResources.Customer_AddressState);
builder.Property(x => x.AddressLine).DisplayName(DevAVDbResources.Customer_AddressLine);
builder.Property(x => x.AddressCity).DisplayName(DevAVDbResources.Customer_AddressCity);
builder.Property(x => x.AddressZipCode).DisplayName(DevAVDbResources.Customer_AddressZipCode);
builder.Property(x => x.Phone).DisplayName(DevAVDbResources.Customer_Phone);
builder.Property(x => x.Fax).DisplayName(DevAVDbResources.Customer_Fax);
builder.Property(x => x.Website).DisplayName(DevAVDbResources.Customer_Website);
builder.Property(x => x.AnnualRevenue).DisplayName(DevAVDbResources.Customer_AnnualRevenue);
builder.Property(x => x.TotalStores).DisplayName(DevAVDbResources.Customer_TotalStores);
builder.Property(x => x.TotalEmployees).DisplayName(DevAVDbResources.Customer_TotalEmployees);
builder.Property(x => x.Status).DisplayName(DevAVDbResources.Customer_Status);
builder.Property(x => x.Logo).DisplayName(DevAVDbResources.Customer_Logo);
}
public static void BuildMetadata(MetadataBuilder<CustomerStore> builder) {
builder.DisplayName(DevAVDbResources.CustomerStore);
builder.Property(x => x.AddressState).DisplayName(DevAVDbResources.CustomerStore_AddressState);
builder.Property(x => x.AddressLine).DisplayName(DevAVDbResources.CustomerStore_AddressLine);
builder.Property(x => x.AddressCity).DisplayName(DevAVDbResources.CustomerStore_AddressCity);
builder.Property(x => x.AddressZipCode).DisplayName(DevAVDbResources.CustomerStore_AddressZipCode);
builder.Property(x => x.State).DisplayName(DevAVDbResources.CustomerStore_State);
builder.Property(x => x.Phone).DisplayName(DevAVDbResources.CustomerStore_Phone);
builder.Property(x => x.Fax).DisplayName(DevAVDbResources.CustomerStore_Fax);
builder.Property(x => x.TotalEmployees).DisplayName(DevAVDbResources.CustomerStore_TotalEmployees);
builder.Property(x => x.SquereFootage).DisplayName(DevAVDbResources.CustomerStore_SquereFootage);
builder.Property(x => x.AnnualSales).DisplayName(DevAVDbResources.CustomerStore_AnnualSales);
builder.Property(x => x.CrestLarge).DisplayName(DevAVDbResources.CustomerStore_CrestLarge);
builder.Property(x => x.CrestSmall).DisplayName(DevAVDbResources.CustomerStore_CrestSmall);
builder.Property(x => x.Location).DisplayName(DevAVDbResources.CustomerStore_Location);
builder.Property(x => x.Customer).DisplayName(DevAVDbResources.CustomerStore_Customer);
}
public static void BuildMetadata(MetadataBuilder<Order> builder) {
builder.DisplayName(DevAVDbResources.Order);
builder.Property(x => x.InvoiceNumber).DisplayName(DevAVDbResources.Order_InvoiceNumber);
builder.Property(x => x.PONumber).DisplayName(DevAVDbResources.Order_PONumber);
builder.Property(x => x.OrderDate).DisplayName(DevAVDbResources.Order_OrderDate);
builder.Property(x => x.SaleAmount).DisplayName(DevAVDbResources.Order_SaleAmount);
builder.Property(x => x.ShippingAmount).DisplayName(DevAVDbResources.Order_ShippingAmount);
builder.Property(x => x.TotalAmount).DisplayName(DevAVDbResources.Order_TotalAmount);
builder.Property(x => x.ShipDate).DisplayName(DevAVDbResources.Order_ShipDate);
builder.Property(x => x.OrderTerms).DisplayName(DevAVDbResources.Order_OrderTerms);
builder.Property(x => x.Customer).DisplayName(DevAVDbResources.Order_Customer);
builder.Property(x => x.Employee).DisplayName(DevAVDbResources.Order_Employee);
builder.Property(x => x.Store).DisplayName(DevAVDbResources.Order_Store);
}
public static void BuildMetadata(MetadataBuilder<Employee> builder) {
builder.DisplayName(DevAVDbResources.Employee);
builder.Property(x => x.FirstName).DisplayName(DevAVDbResources.Employee_FirstName);
builder.Property(x => x.LastName).DisplayName(DevAVDbResources.Employee_LastName);
builder.Property(x => x.Prefix).DisplayName(DevAVDbResources.Employee_Prefix);
builder.Property(x => x.HomePhone).DisplayName(DevAVDbResources.Employee_HomePhone);
builder.Property(x => x.MobilePhone).DisplayName(DevAVDbResources.Employee_MobilePhone);
builder.Property(x => x.Email).DisplayName(DevAVDbResources.Employee_Email);
builder.Property(x => x.Skype).DisplayName(DevAVDbResources.Employee_Skype);
builder.Property(x => x.BirthDate).DisplayName(DevAVDbResources.Employee_BirthDate);
builder.Property(x => x.Picture).DisplayName(DevAVDbResources.Employee_Picture);
builder.Property(x => x.AddressState).DisplayName(DevAVDbResources.Employee_AddressState);
builder.Property(x => x.AddressLine).DisplayName(DevAVDbResources.Employee_AddressLine);
builder.Property(x => x.AddressCity).DisplayName(DevAVDbResources.Employee_AddressCity);
builder.Property(x => x.AddressZipCode).DisplayName(DevAVDbResources.Employee_AddressZipCode);
builder.Property(x => x.Department).DisplayName(DevAVDbResources.Employee_Department);
builder.Property(x => x.Title).DisplayName(DevAVDbResources.Employee_Title);
builder.Property(x => x.Status).DisplayName(DevAVDbResources.Employee_Status);
builder.Property(x => x.HireDate).DisplayName(DevAVDbResources.Employee_HireDate);
builder.Property(x => x.PersonalProfile).DisplayName(DevAVDbResources.Employee_PersonalProfile);
builder.Property(x => x.Order).DisplayName(DevAVDbResources.Employee_Order);
}
public static void BuildMetadata(MetadataBuilder<EmployeeTask> builder) {
builder.DisplayName(DevAVDbResources.EmployeeTask);
builder.Property(x => x.Subject).DisplayName(DevAVDbResources.EmployeeTask_Subject);
builder.Property(x => x.Description).DisplayName(DevAVDbResources.EmployeeTask_Description);
builder.Property(x => x.StartDate).DisplayName(DevAVDbResources.EmployeeTask_StartDate);
builder.Property(x => x.DueDate).DisplayName(DevAVDbResources.EmployeeTask_DueDate);
builder.Property(x => x.Status).DisplayName(DevAVDbResources.EmployeeTask_Status);
builder.Property(x => x.Priority).DisplayName(DevAVDbResources.EmployeeTask_Priority);
builder.Property(x => x.Completion).DisplayName(DevAVDbResources.EmployeeTask_Completion);
builder.Property(x => x.Reminder).DisplayName(DevAVDbResources.EmployeeTask_Reminder);
builder.Property(x => x.ReminderDateTime).DisplayName(DevAVDbResources.EmployeeTask_ReminderDateTime);
builder.Property(x => x.AssignedEmployee).DisplayName(DevAVDbResources.EmployeeTask_AssignedEmployee);
}
public static void BuildMetadata(MetadataBuilder<Quote> builder) {
builder.DisplayName(DevAVDbResources.Quote);
builder.Property(x => x.Number).DisplayName(DevAVDbResources.Quote_Number);
builder.Property(x => x.Date).DisplayName(DevAVDbResources.Quote_Date);
builder.Property(x => x.SubTotal).DisplayName(DevAVDbResources.Quote_SubTotal);
builder.Property(x => x.ShippingAmount).DisplayName(DevAVDbResources.Quote_ShippingAmount);
builder.Property(x => x.Total).DisplayName(DevAVDbResources.Quote_Total);
builder.Property(x => x.Opportunity).DisplayName(DevAVDbResources.Quote_Opportunity);
builder.Property(x => x.Customer).DisplayName(DevAVDbResources.Quote_Customer);
builder.Property(x => x.CustomerStore).DisplayName(DevAVDbResources.Quote_CustomerStore);
builder.Property(x => x.Employee).DisplayName(DevAVDbResources.Quote_Employee);
}
public static void BuildMetadata(MetadataBuilder<Product> builder) {
builder.DisplayName(DevAVDbResources.Product);
builder.Property(x => x.Name).DisplayName(DevAVDbResources.Product_Name);
builder.Property(x => x.Description).DisplayName(DevAVDbResources.Product_Description);
builder.Property(x => x.ProductionStart).DisplayName(DevAVDbResources.Product_ProductionStart);
builder.Property(x => x.Available).DisplayName(DevAVDbResources.Product_Available);
builder.Property(x => x.Image).DisplayName(DevAVDbResources.Product_Image);
builder.Property(x => x.CurrentInventory).DisplayName(DevAVDbResources.Product_CurrentInventory);
builder.Property(x => x.Backorder).DisplayName(DevAVDbResources.Product_Backorder);
builder.Property(x => x.Manufacturing).DisplayName(DevAVDbResources.Product_Manufacturing);
builder.Property(x => x.Barcode).DisplayName(DevAVDbResources.Product_Barcode);
builder.Property(x => x.Cost).DisplayName(DevAVDbResources.Product_Cost);
builder.Property(x => x.SalePrice).DisplayName(DevAVDbResources.Product_SalePrice);
builder.Property(x => x.RetailPrice).DisplayName(DevAVDbResources.Product_RetailPrice);
builder.Property(x => x.ConsumerRating).DisplayName(DevAVDbResources.Product_ConsumerRating);
builder.Property(x => x.Category).DisplayName(DevAVDbResources.Product_Category);
builder.Property(x => x.Engineer).DisplayName(DevAVDbResources.Product_Engineer);
builder.Property(x => x.Support).DisplayName(DevAVDbResources.Product_Support);
}
}
}
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataAnnotations;
using System.Collections.ObjectModel;
using DevExpress.Data.Linq;
using System.Collections;
using DevExpress.Mvvm.ViewModel;
using DevExpress.Mvvm.DataModel;
namespace DevExpress.DevAV.Common {
public partial class InstantFeedbackCollectionViewModel<TEntity, TPrimaryKey, TUnitOfWork> : InstantFeedbackCollectionViewModelBase<TEntity, TEntity, TPrimaryKey, TUnitOfWork>
where TEntity : class, new()
where TUnitOfWork : IUnitOfWork {
public static InstantFeedbackCollectionViewModel<TEntity, TPrimaryKey, TUnitOfWork> CreateInstantFeedbackCollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IRepository<TEntity, TPrimaryKey>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TEntity>> projection = null,
Func<bool> canCreateNewEntity = null) {
return ViewModelSource.Create(() => new InstantFeedbackCollectionViewModel<TEntity, TPrimaryKey, TUnitOfWork>(unitOfWorkFactory, getRepositoryFunc, projection, canCreateNewEntity));
}
protected InstantFeedbackCollectionViewModel(
IUnitOfWorkFactory<TUnitOfWork> unitOfWorkFactory,
Func<TUnitOfWork, IRepository<TEntity, TPrimaryKey>> getRepositoryFunc,
Func<IRepositoryQuery<TEntity>, IQueryable<TEntity>> projection = null,
Func<bool> canCreateNewEntity = null)
: base(unitOfWorkFactory, getRepositoryFunc, projection, canCreateNewEntity) {
}
}
}
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataModel;
using DevExpress.DevAV.ViewModels;
namespace DevExpress.DevAV.Common {
partial class CollectionViewModel<TEntity, TProjection, TPrimaryKey, TUnitOfWork> : ISupportFiltering<TEntity>, IFilterTreeViewModelContainer<TEntity, TPrimaryKey>
where TEntity : class
where TProjection : class
where TUnitOfWork : IUnitOfWork {
public virtual FilterTreeViewModel<TEntity, TPrimaryKey> FilterTreeViewModel { get; set; }
public void CreateCustomFilter() {
Messenger.Default.Send(new CreateCustomFilterMessage<TEntity>());
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq.Expressions;
namespace DevExpress.DevAV.ViewModels {
public class FilterTreeModelPageSpecificSettings<TSettings> : IFilterTreeModelPageSpecificSettings where TSettings : ApplicationSettingsBase {
readonly string staticFiltersTitle;
readonly string customFiltersTitle;
readonly TSettings settings;
readonly PropertyDescriptor customFiltersProperty;
readonly PropertyDescriptor staticFiltersProperty;
readonly IEnumerable<string> hiddenFilterProperties;
readonly IEnumerable<string> additionalFilterProperties;
public FilterTreeModelPageSpecificSettings(TSettings settings, string staticFiltersTitle,
Expression<Func<TSettings, FilterInfoList>> getStaticFiltersExpression, Expression<Func<TSettings, FilterInfoList>> getCustomFiltersExpression,
IEnumerable<string> hiddenFilterProperties = null, IEnumerable<string> additionalFilterProperties = null, string customFiltersTitle = "Custom Filters") {
this.settings = settings;
this.staticFiltersTitle = staticFiltersTitle;
this.customFiltersTitle = customFiltersTitle;
staticFiltersProperty = GetProperty(getStaticFiltersExpression);
customFiltersProperty = GetProperty(getCustomFiltersExpression);
this.hiddenFilterProperties = hiddenFilterProperties;
this.additionalFilterProperties = additionalFilterProperties;
}
FilterInfoList IFilterTreeModelPageSpecificSettings.CustomFilters
{
get { return GetFilters(customFiltersProperty); }
set { SetFilters(customFiltersProperty, value); }
}
FilterInfoList IFilterTreeModelPageSpecificSettings.StaticFilters
{
get { return GetFilters(staticFiltersProperty); }
set { SetFilters(staticFiltersProperty, value); }
}
string IFilterTreeModelPageSpecificSettings.StaticFiltersTitle { get { return staticFiltersTitle; } }
string IFilterTreeModelPageSpecificSettings.CustomFiltersTitle { get { return customFiltersTitle; } }
IEnumerable<string> IFilterTreeModelPageSpecificSettings.HiddenFilterProperties { get { return hiddenFilterProperties; } }
IEnumerable<string> IFilterTreeModelPageSpecificSettings.AdditionalFilterProperties { get { return additionalFilterProperties; } }
void IFilterTreeModelPageSpecificSettings.SaveSettings() {
settings.Save();
}
PropertyDescriptor GetProperty(Expression<Func<TSettings, FilterInfoList>> expression) {
if(expression != null)
return TypeDescriptor.GetProperties(settings)[GetPropertyName(expression)];
return null;
}
FilterInfoList GetFilters(PropertyDescriptor property) {
return property != null ? (FilterInfoList)property.GetValue(settings) : null;
}
void SetFilters(PropertyDescriptor property, FilterInfoList value) {
if(property != null)
property.SetValue(settings, value);
}
static string GetPropertyName(Expression<Func<TSettings, FilterInfoList>> expression) {
MemberExpression memberExpression = expression.Body as MemberExpression;
if(memberExpression == null) {
throw new ArgumentException("expression");
}
return memberExpression.Member.Name;
}
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class QuoteView : UserControl {
public QuoteView() {
InitializeComponent();
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.CustomerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
xmlns:dxrudex="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesignerextensions"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:viewModel="clr-namespace:DevExpress.DevAV.ViewModels"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
xmlns:localization="clr-namespace:DevExpress.DevAV.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" DataContext="{dxmvvm:ViewModelSource viewModel:CustomerViewModel}">
<UserControl.Resources>
<ResourceDictionary Source="../../Resources/EntityViewResources.xaml" />
</UserControl.Resources>
<DockPanel Style="{StaticResource EntityView.RootContainer}">
<dxwui:AppBar DockPanel.Dock="Bottom" Style="{StaticResource EntityView.AppBar}">
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Save}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndClose}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.SaveAndNew}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Reset}" />
<dxwui:AppBarButton Style="{StaticResource EntityView.Command.Delete}" />
</dxwui:AppBar>
<dxlc:DataLayoutControl x:Name="layoutControl" Style="{StaticResource EntityView.DataLayoutControl}">
<dxlc:DataLayoutItem x:Name="layoutItemName" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAddressState" Binding="{Binding AddressState, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAddressLine" Binding="{Binding AddressLine, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAddressCity" Binding="{Binding AddressCity, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAddressZipCode" Binding="{Binding AddressZipCode, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemPhone" Binding="{Binding Phone, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemFax" Binding="{Binding Fax, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemWebsite" Binding="{Binding Website, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemAnnualRevenue" Binding="{Binding AnnualRevenue, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemTotalStores" Binding="{Binding TotalStores, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemTotalEmployees" Binding="{Binding TotalEmployees, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:DataLayoutItem x:Name="layoutItemStatus" Binding="{Binding Status, UpdateSourceTrigger=PropertyChanged}" />
<dxlc:LayoutGroup x:Name="Tabs" View="Tabs" MinHeight="250">
<dxlc:LayoutGroup Style="{StaticResource EntityView.Detail.Container}" DataContext="{Binding CustomerOrdersDetails}" dxlc:LayoutControl.TabHeader="Orders">
<dxg:GridControl x:Name="CustomerOrdersDetailsGrid" dx:DXSerializer.SerializationID="CustomerOrdersDetailsGrid" Style="{StaticResource EntityView.Detail.GridControl.Editable}">
<dxg:GridControl.View>
<dxg:TableView Style="{StaticResource EntityView.Detail.TableView}" />
</dxg:GridControl.View>
<dxg:GridControl.Columns>
<dxg:GridColumn IsSmart="True" FieldName="InvoiceNumber" />
<dxg:GridColumn IsSmart="True" FieldName="PONumber" />
<dxg:GridColumn IsSmart="True" FieldName="OrderDate" />
<dxg:GridColumn IsSmart="True" FieldName="SaleAmount" />
<dxg:GridColumn IsSmart="True" FieldName="ShippingAmount" />
<dxg:GridColumn IsSmart="True" FieldName="TotalAmount" />
<dxg:GridColumn IsSmart="True" FieldName="ShipDate" />
<dxg:GridColumn IsSmart="True" FieldName="OrderTerms" />
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Count" Alignment="Right" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.GroupSummary>
<dxg:GridSummaryItem SummaryType="Count" />
</dxg:GridControl.GroupSummary>
</dxg:GridControl>
<dxlc:LayoutGroup Orientation="Vertical" HorizontalAlignment="Right" VerticalAlignment="Top" MinWidth="100">
<Button Style="{StaticResource EntityView.Detail.Command.New}" />
<Button Style="{StaticResource EntityView.Detail.Command.Edit}" />
<Button Style="{StaticResource EntityView.Detail.Command.Delete}" />
<Button Style="{StaticResource EntityView.Detail.Command.Refresh}" />
<Button Style="{StaticResource EntityView.Detail.Command.Save}" />
<Button Style="{StaticResource EntityView.Detail.Command.Reset}" />
</dxlc:LayoutGroup>
</dxlc:LayoutGroup>
<dxlc:LayoutGroup Style="{StaticResource EntityView.Detail.Container}" DataContext="{Binding CustomerQuotesDetails}" dxlc:LayoutControl.TabHeader="Quotes">
<dxg:GridControl x:Name="CustomerQuotesDetailsGrid" dx:DXSerializer.SerializationID="CustomerQuotesDetailsGrid" Style="{StaticResource EntityView.Detail.GridControl.Editable}">
<dxg:GridControl.View>
<dxg:TableView Style="{StaticResource EntityView.Detail.TableView}" />
</dxg:GridControl.View>
<dxg:GridControl.Columns>
<dxg:GridColumn IsSmart="True" FieldName="Number" />
<dxg:GridColumn IsSmart="True" FieldName="Date" />
<dxg:GridColumn IsSmart="True" FieldName="SubTotal" />
<dxg:GridColumn IsSmart="True" FieldName="ShippingAmount" />
<dxg:GridColumn IsSmart="True" FieldName="Total" />
<dxg:GridColumn IsSmart="True" FieldName="Opportunity" />
</dxg:GridControl.Columns>
<dxg:GridControl.TotalSummary>
<dxg:GridSummaryItem SummaryType="Count" Alignment="Right" />
</dxg:GridControl.TotalSummary>
<dxg:GridControl.GroupSummary>
<dxg:GridSummaryItem SummaryType="Count" />
</dxg:GridControl.GroupSummary>
</dxg:GridControl>
<dxlc:LayoutGroup Orientation="Vertical" HorizontalAlignment="Right" VerticalAlignment="Top" MinWidth="100">
<Button Style="{StaticResource EntityView.Detail.Command.New}" />
<Button Style="{StaticResource EntityView.Detail.Command.Edit}" />
<Button Style="{StaticResource EntityView.Detail.Command.Delete}" />
<Button Style="{StaticResource EntityView.Detail.Command.Refresh}" />
<Button Style="{StaticResource EntityView.Detail.Command.Save}" />
<Button Style="{StaticResource EntityView.Detail.Command.Reset}" />
</dxlc:LayoutGroup>
</dxlc:LayoutGroup>
</dxlc:LayoutGroup>
</dxlc:DataLayoutControl>
</DockPanel>
</UserControl>
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the single Product object view model.
/// </summary>
public partial class ProductViewModel : SingleObjectViewModel<Product, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of ProductViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static ProductViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new ProductViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the ProductViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the ProductViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected ProductViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Products, x => x.Name) {
}
/// <summary>
/// The view model that contains a look-up collection of Employees for the corresponding navigation property in the view.
/// </summary>
public IEntitiesViewModel<Employee> LookUpEmployees
{
get
{
return GetLookUpEntitiesViewModel(
propertyExpression: (ProductViewModel x) => x.LookUpEmployees,
getRepositoryFunc: x => x.Employees);
}
}
}
}
using System.Windows.Controls;
namespace DevExpress.DevAV.Views {
public partial class QuoteCollectionView : UserControl {
public QuoteCollectionView() {
InitializeComponent();
}
}
}
using System;
using System.Linq;
using DevExpress.Mvvm.POCO;
using DevExpress.Mvvm.DataModel;
using DevExpress.Mvvm.ViewModel;
using DevExpress.DevAV.DevAVDbDataModel;
using DevExpress.DevAV.Common;
using DevExpress.DevAV;
namespace DevExpress.DevAV.ViewModels {
/// <summary>
/// Represents the Employees collection view model.
/// </summary>
public partial class EmployeeCollectionViewModel : CollectionViewModel<Employee, long, IDevAVDbUnitOfWork> {
/// <summary>
/// Creates a new instance of EmployeeCollectionViewModel as a POCO view model.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
public static EmployeeCollectionViewModel Create(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null) {
return ViewModelSource.Create(() => new EmployeeCollectionViewModel(unitOfWorkFactory));
}
/// <summary>
/// Initializes a new instance of the EmployeeCollectionViewModel class.
/// This constructor is declared protected to avoid undesired instantiation of the EmployeeCollectionViewModel type without the POCO proxy factory.
/// </summary>
/// <param name="unitOfWorkFactory">A factory used to create a unit of work instance.</param>
protected EmployeeCollectionViewModel(IUnitOfWorkFactory<IDevAVDbUnitOfWork> unitOfWorkFactory = null)
: base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Employees) {
}
}
}
using System;
using System.Data.Entity;
namespace DevExpress.DevAV.Generator {
public class DatabaseInitializer : CreateDatabaseIfNotExists<DevAVDb> {
protected override void Seed(DevAVDb context) {
var generator = new DatabaseGenerator();
base.Seed(context);
generator.Seed(context);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Shapes;
using DevExpress.Xpf.Core;
namespace DevExpress.HybridApp {
/// <summary>
/// Interaction logic for LoadingSplashScreen.xaml
/// </summary>
public partial class LoadingSplashScreen : UserControl {
public LoadingSplashScreen() {
InitializeComponent();
}
}
}
using DevExpress.Utils;
using System;
using System.Windows;
using System.Windows.Media.Imaging;
namespace DevExpress.DevAV {
public static class Converters {
public static BitmapImage LocalUriToImage(string value) {
return value != null ? new BitmapImage(AssemblyHelper.GetResourceUri(typeof(Converters).Assembly, value)) : null;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Shapes;
using DevExpress.Xpf.Core;
namespace DevExpress.DevAV.Data.Generator {
/// <summary>
/// Interaction logic for GenerateDBSplashScreen.xaml
/// </summary>
public partial class GenerateDBSplashScreen : UserControl {
public GenerateDBSplashScreen() {
InitializeComponent();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 DevExpress.DevAV.Views {
public partial class StaticFiltersPanel : UserControl {
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(StaticFiltersPanel), new PropertyMetadata(null));
public StaticFiltersPanel() {
InitializeComponent();
}
}
}
<UserControl x:Class="DevExpress.DevAV.Views.CustomFilterView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:devav="clr-namespace:DevExpress.DevAV"
xmlns:view="clr-namespace:DevExpress.DevAV.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel Margin="12,12,12,0">
<dxe:TextEdit NullText="Enter a name for your custom filter..." DockPanel.Dock="Bottom" EditValue="{Binding FilterName}"/>
<StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Left" Margin="0,10">
<dxe:CheckEdit Content="Save for future use" EditValue="{Binding Save}"/>
</StackPanel>
<dxe:FilterControl x:Name="FilterControl" FilterCriteria="{Binding FilterCriteria, Mode=TwoWay}" MinWidth="500" MinHeight="200">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="IsVisibleChanged" Command="{Binding ElementName=FilterControl, Path=ApplyFilterCommand}" />
<view:CustomFilterControlColumnsBehavior ObjectType="{Binding EntityType}" UpperCasePropertyNames="True" HiddenProperties="{Binding HiddenProperties}" AdditionalProperties="{Binding AdditionalProperties, Converter={dxmvvm:EnumerableConverter {dxmvvm:ReflectionConverter}}}"/>
</dxmvvm:Interaction.Behaviors>
</dxe:FilterControl>
</DockPanel>
</UserControl>