The One With

April 2010 - Posts

  • Silverlight Outlook and Explorer Style NavBar Control – v2010 vol 1

    A quick heads up on the upcoming NavBar control for Silverlight.

    The Explorer View The Side Bar View
    Silverlight NarBar Control - Explorer View Silverlight NavBar Control - Side Bar View
    Microsoft Outlook Style View
    Silverlight NavBar Control - Microsoft Outlook View

    Creating a NavBar in XAML

    The internal Groups/Items structure is very intuitive:

    • NavBarControl
      • NavBarControl.Groups [NavBarGroup]
        • NavBarGroup.Items [NavBarItem]

    xmlns:dxn=”http://schemas.devexpress.com/winfx/2008/xaml/navbar
    <dxn:NavBarControl>
    <dxn:NavBarGroup Header="Group1">
    <dxn:NavBarItem Content="Item1">
    </dxn:NavBarItem>
    <dxn:NavBarItem Content="Item2">
    </dxn:NavBarItem>
    <dxn:NavBarItem Content="Item3">
    </dxn:NavBarItem>
    </dxn:NavBarGroup>
    <dxn:NavBarGroup Header="Group2">
    <dxn:NavBarItem Content="Item1">
    </dxn:NavBarItem>
    <dxn:NavBarItem Content="Item3">
    </dxn:NavBarItem>
    <dxn:NavBarItem Content="Item3">
    </dxn:NavBarItem>
    </dxn:NavBarGroup>
    </dxn:NavBarControl.Groups>
    </dxn:NavBarControl>


    Creating a NavBar in Code

    DevExpress.Xpf.NavBar.NavBarGroup group = new DevExpress.Xpf.NavBar.NavBarGroup() { 
    Header = "Group 1"
    };

    group.Items.Add(
    new NavBarItem() {
    Content = "Item 1"
    }
    );
    group.Items.Add(
    new NavBarItem() {
    Content = "Item 2"
    }
    );

    navBar.Groups.Add(group);

    Cheers

    Azret

  • Silverlight Report Viewer and the XtraReports End User Report Designer - v2010 vol 1

    In my previous post I have showed you how to display an XtraReport inside a Silverlight application. The assumptions we made last time were that the reports are created by the developer and that they are compiled into the solution. This is not always the case in the real world. Especially when we are working with XtraReports, because it comes with a full end-user report designer.

    To dynamically build the reports on the server and to bypass the default registration mechanism of the IReportService (which uses a fully qualified report type name to create report instances) we will override the IReportService.StartBuild.  We’ll treat the passed in reportTypeName argument as a file name of the report previously saved by the end-user report designer.

    End User Report Designer

    To load the report file, we’ll use the XtraReport.LoadLayout. For example let’s assume that all our reports are saved into a special ~/Reports folder on the server: 

    public class ReportService : DevExpress.XtraReports.Service.ReportService, IReportService {
    const string NoDocumentMsg = "There is no such documentId";
    const string NoSessionMsg = "there is no session";
    const string NoReportMsg = "There is no such report";

    const string filePath = "~/Reports";
    public override DevExpress.XtraReports.Service.DataContracts.DocumentId StartBuild(string reportTypeName) {
    if (Session == null || User == null)
    throw new FaultException(NoSessionMsg);
    XtraReport report = new XtraReport();
    report.LoadLayout(HttpContext.Current.Server.MapPath(filePath + "//" + reportTypeName));
    return ReportServiceContainer.Builder.StartBuild(report, Session, null);
    }
    }

    With this new ReportService implementation, you would now request the reports by the file name like so:

    ReportPreviewModel model = new ReportPreviewModel();
    model.ReportTypeName = "XtraReport1.repx";

    previewControl.Model = model;
    model.CreateDocument();

    I have uploaded a sample that shows how to open any report file from your Silverlight application. Download it here.

    Silverlight End User Report Viewer

    Silverlight End User Report Viewer

    Cheers

    Azret

  • Silverlight Drag and Drop – v2010 vol 1

    v2010.1 has a new undocumented drag and drop library that is used internally by our controls. The code for it lives in DevExpress.Xpf.Core and is abstract enough to be reused. If you need drag and drop support in your Silverlight apps, please download the DevExpress.Xpf.Core.Extensions from http://community.devexpress.com/files/folders/samples/entry302886.aspx.

    To setup a drag source all you have to do is set the Allow Drag property on your control. For example to drag from a ListBox

    xmlns:dnd="clr-namespace:DevExpress.Xpf.Core.DragAndDrop;assembly=DevExpress.Xpf.Core.Extensions.v10.1"

    <ListBox Name="listBox1" dnd:DragAndDropManager.AllowDrag="True">
    </ListBox>
     
    When AllowDrag is set, a default drag cursor will be provided for the drag operations. We can control that by registering a custom IDragAndDropHandler for our source.
     
    // Provides app level feedback to the Drag and Drop manager
    public interface IDragAndDropHandler {
    bool CanStartDrag(UIElement source, MouseButtonEventArgs e, ref object dragData);
    FrameworkElement CreateDragThumb(UIElement source, UIElement target, object dragData);
    }

    To setup a drop target, set the AllowDrop for your target element and implement DragOver, DragLeave and Drop events. In this events, you will receive the drag source and the associated drag data so that you can respond appropriately.

    An example of drag and drop between ListBox controls with a custom drag cursor:
     
    <Grid Margin="20">
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"></ColumnDefinition>
    <ColumnDefinition Width="30"></ColumnDefinition>
    <ColumnDefinition Width="*"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <ListBox Name="listBox1" dnd:DragAndDropManager.AllowDrag="True">
    <ListBox.ItemTemplate>
    <DataTemplate>
    <Image Source="{Binding}"></Image>
    </DataTemplate>
    </ListBox.ItemTemplate>
    </ListBox>
    <ListBox Name="listBox2" Grid.Column="2"
    dnd:DragAndDropManager.AllowDrop="True"
    dnd:DragAndDropManager.DragLeave="ListBox2_DragLeave"
    dnd:DragAndDropManager.DragOver="ListBox2_DragOver"
    dnd:DragAndDropManager.Drop="ListBox2_Drop">
    <ListBox.ItemTemplate>
    <DataTemplate>
    <Image Source="{Binding}"></Image>
    </DataTemplate>
    </ListBox.ItemTemplate>
    </ListBox>
    </Grid>
     
    public partial class MainPage : UserControl, IDragAndDropHandler {
    public MainPage() {
    InitializeComponent();
    listBox1.ItemsSource = new ObservableCollection<string>() {
    "WIN-ICON.png",
    "ASP-ICON.png",
    "WPF-ICON.png",
    "AG-ICON.png",
    "VCL-ICON.png",
    "APP-ICON.png",
    "IDE-ICON.png",
    "OTHER-ICON.png",
    };
    listBox2.ItemsSource = new ObservableCollection<string>();
    DragAndDropManager.RegisterHandler(listBox1, this);
    }

    #region Drag Soource
    static ListBoxItem GetHotItem(MouseButtonEventArgs e) {
    ListBoxItem dragItem = null;
    DependencyObject dep = (DependencyObject)e.OriginalSource;
    while (dep != null) {
    dragItem = dep as ListBoxItem;
    if (dragItem != null) {
    break;
    }
    dep = VisualTreeHelper.GetParent(dep);
    }
    return dragItem;
    }
    bool IDragAndDropHandler.CanStartDrag(UIElement source, MouseButtonEventArgs e, ref object dragData) {
    dragData = GetHotItem(e);
    // Only Allow Dragging if we are on a ListBoxItem
    return dragData != null;
    }
    FrameworkElement IDragAndDropHandler.CreateDragThumb(UIElement source, UIElement target, object dragData) {
    // Override the default drag cursor
    Image img = new Image();
    BitmapImage bi = new BitmapImage(new Uri(((ListBoxItem)dragData).Content as string, UriKind.Relative));
    img.Source = bi;
    img.Opacity = 0.6;
    return img;
    }
    #endregion

    #region Drop Target
    public void ListBox2_DragOver(object sender, DragAndDropEventArgs e) {
    // Only Accept objects from listBox1
    e.Accept = e.Source == listBox1;
    }

    public void ListBox2_DragLeave(object sender, DragAndDropEventArgs e) {
    }

    public void ListBox2_Drop(object sender, DragAndDropEventArgs e) {
    ObservableCollection<string> source = ((System.Windows.Controls.ListBox)e.Source).ItemsSource as ObservableCollection<string>;
    ObservableCollection<string> dest = ((System.Windows.Controls.ListBox)sender).ItemsSource as ObservableCollection<string>;

    string item = (string)((ListBoxItem)e.DragData).Content;
    source.Remove(item);
    dest.Add(item);
    }
    #endregion
    }


    Silverlight Drag and Drop

    Cheers,

    Azret

  • Silverlight Report Viewer – v2010 vol 1

    Last week we made two big announcements regarding our Reporting Suite. The first one is that it will fully support Visual Studio 2010 and the second one is that we are introducing Report Viewer controls for both WPF and Silverlight.

    I know a lot of you have been waiting for the Silverlight Viewer so here is a step by step to get you started.  Note: If you are not familiar with creating reports, you can quickly catch up by watching the XtraReports How-To Videos:

    DocumentPreview

    The reports are rendered using a new DocumentPreview (DevExpress.Xpf.Printing.DocumentPreview) from our printing library. The DocumentPreview knows nothing about the reports themselves. It is the job of DocumentPreview.Model (an IDocumentPreviewModel) to provide the necessary plumbing.

    namespace DevExpress.Xpf.Printing {
    public interface IDocumentPreviewModel : INotifyPropertyChanged {
    int CurrentPageIndex { get; set; }
    int PageCount { get; }
    void CreateDocument();
    ...
    }
    }
     
    An implementation of one that works via WCF Web Services can be found in DevExpress.Xpf.Printing.ReportPreviewModel. This is the one we will be using to query for our XtraReports from the Silverlight App.

    IReportService

    Under the hood, ReportPreviewModel will communicate using an IReportService service contract:

    public interface IReportService {
    IList<ReportInfo> GetAvailableReports();
    ...
    DocumentId StartBuild(string reportTypeName);
    void StopBuild(DocumentId documentId);
    }

    so we must publish it on our server. The fastest way to do this is to create a new Silverlight-enabled WCF Service and then inherit it from a build ReportService. For example I will call it XtraReportService.

    [ServiceContract]
    public interface IXtraReportService : XtraReports.Service.IReportService {
    // TODO: Add Custom Service Operations
    }

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class XtraReportService : XtraReports.Service.ReportService, IXtraReportService {
    }
     
    The WCF Service wizard will add the default config. settings for your new service. Change the contract to your IXtraReportService.
     
    <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
    <behaviors>
    <serviceBehaviors>
    <behavior name="">
    <serviceMetadata httpGetEnabled="true"/>
    <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <bindings>
    <customBinding>
    <binding name="XtraReportServiceBinding">
    <binaryMessageEncoding/>
    <httpTransport/>
    </binding>
    </customBinding>
    </bindings>
    <services>
    <service name="DevExpress.Samples.ReportViewer.Web.ReportService">
    <endpoint address="" binding="customBinding" bindingConfiguration="XtraReportServiceBinding" contract="[FULL NAMESPACE].IXtraReportService"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
    </services>
    </system.serviceModel>
     

    Registering Reports

    Now that we have the Report Service ready we need to tell it which XtraReport reports are available. This can be done in the config. file using a special DevExpress.XtraReports section. For example I can register my CustomerListReport in Web.config.

    <DevExpress.XtraReport>
    <RegisteredReports>
    <Report TypeName="[Full XtraReport Type name]" Description="Customer List" Name="CustomerListReport">
    <Permissions>
    <add Action="Allow" Users="*" />
    </Permissions>
    </Report>
    </RegisteredReports>
    </DevExpress.XtraReport>
     
    or register it in code:
     
    ReportServiceContainer.Accessor.RegisterReport(
    new DevExpress.XtraReports.Service.Common.Access.RegisteredReportInfo() {
    DisplayName = "Customer List",
    Permissions = new IReportPermission[] {
    new ReportPermission(System.Web.Configuration.AuthorizationRuleAction.Allow, "*")
    },
    ReportType = typeof(MyNamespace.XtraReport_CustomerList)
    });

    UI

    To display the report, drop the DocumentPreviewControl on your Silverlight page.

    xmlns:my="clr-namespace:DevExpress.Xpf.Printing;assembly=DevExpress.Xpf.Printing.v10.1"
     
    <my:DocumentPreviewControl Name="documentPreviewControl1"/>
     
    and then query for it somewhere like so:
     
    private void button2_Click(object sender, RoutedEventArgs e) {
    ReportPreviewModel previewModel = new ReportPreviewModel();
    previewModel.ReportTypeName = "MyNamespace.XtraReport_CustomerList";

    documentPreviewControl1.Model = previewModel;

    previewModel.CreateDocument();
    }
     
    Silverlight Report Viewer

     

     

     

    Cheers,

    Azret

  • Silverlight Grid - Unbound Columns and Expression Editor – v2010 vol 1

    The AgDataGrid in v2010.1 will introduce a new set of features to work with unbound columns. Now, it was possible to do unbound or calculated columns before but the approaches used to accomplish those had limitations.

    For example you could add a “calculated field” (a.k.a a Read only property) to your data objects but you loose the flexibility to customize the value at runtime and, you start bloating your data objects with unnecessary logic. You could also override how the value is to be displayed but by doing so, you loose the ability to perform sorting, grouping and filtering on that ”new” display value.

    The AgDataGrid in v2010.1 gives you a new CustomUnboundColumnData event where you can set a value for the cell and a new AgDataGridColumn.UnboundExpression where you can specify an expression to calculate the value. For example suppose you have a Parts table with Columns like Part ID, Part Name, Quantity, Price. And you want to display the Total Cost in the grid as Price * Quantity.

    <dxg:AgDataGrid>
    <dxg:AgDataGrid.Columns>
    <dxg:AgDataGridColumn FieldName="PartID"/>
    <dxg:AgDataGridColumn FieldName="Price"/>
    <dxg:AgDataGridColumn FieldName="Quantity"/>
    <dxg:AgDataGridColumn FieldName="Total" UnboundExpression="[Price] * [Quantity]"/>
    </dxg:AgDataGrid.Columns>
    </dxg:AgDataGrid>

    The Grid will also have a build-in expression editor so you can let your end-users do it themselves.

    Silverlight Expression Editor

    Cheers,

    Azret

  • Silverlight Filter Editor – v2010 vol 1

    DXperience v2010.1 will introduce a new Filter Control to let the end-users build complex filter criteria.

    Operators

    Silverlight Filter Editor

    Conditions 

    Silverlight Filter Editor

    In addition to the standard comparisons like equal, greater than etc…, DateTime fields have an additional set of date specific conditions.

    Silverlight Filter Editor

    Cheers

    Azret

  • Silverlight Grid Control and Data Annotations – v2010 vol 1

    AgDataGrid in v2010.1 will introduce support for Data Annotations. This is especially useful if you have adopted .NET RIA Services for your data transport.

    In the first release the DataGrid will support the following annotation attributes from System.ComponentModel.DataAnnotations

    DisplayAttribute

    - Order This will tell the grid the position of the field column

    - ShortName & Description Will control the column header and tooltip

    - AutoGenerateField If this value is set to false the column will not be shown in the grid when auto generates it’s columns from the data source.

    EditableAttribute will control whether an end-user can invoke the in-place editor or not.

    Example:

    public class Customer {
    public string FirstName {
    get;
    set;
    }
    public string LastName {
    get;
    set;
    }
    [Display(ShortName = "Title", Description = "Title of Courtesy")]
    public string TitleOfCourtesy {
    get;
    set;
    }
    [Display(ShortName="Post", Description="Postal Code (editing is not allowed)"), Editable(false)]
    public string PostalCode {
    get;
    set;
    }
    [Display(AutoGenerateField = false, Description="Hidden")]
    public string Extension {
    get;
    set;
    }
    [ReadOnly(true), Display(Order=0, Description="Identifier")]
    public int ID {
    get;
    set;
    }
    }

    Note: we have also added support for the ReadOnlyAttribute

    Cheers,

    Azret

  • New Silverlight and WPF Editors – v2010 vol 1

    I have described earlier about the merge of WPF and Silverlight into XPF. I should mention now that data editors will now live in DevExpress.Xpf.Core assembly instead of the old DevExpress.AgEditors/DevExpress.Wpf.Editors.  The editors are used extensively by other products in the suite (DataGrid, Bars, Pivot Grid etc…) so moving them to core made more sense then creating a new DevExpress.Xpf.Editors assembly.

    A couple of new editors that have made it into v2010.1

    SpinEdit

    Silverlight and WPF Spin Editor

    Spin Editor will support decimals and will support two modes. Editable mode will let you type the values and Non-Editable will only let you increment the values using the spin buttons.

    MemoEdit

    Silverlight and WPF Text Editor

    Memo Edit will allow you enter multi-line text.

    A very new and cool TrackEdit

    Silverlight and WPF Track Bar Control

    Track Editor is similar to a Slider control in functionality except it can manage ranges and zooms just like in Microsoft Office.

    ListBoxEdit

    Silverlight and WPF List Box Control

    The List Box Editor will fully support multi-select mode, check and radio items and when used as an embedded editor, will be able to load it’s display values from a lookup field while allowing the the edit values to be bound to a key field.

     

    Cheers,

    Azret

  • Silverlight Upload Control – v2010 vol 1

    With DXperience v2010.1 we are introducing a couple of new Silverlight only controls. One of them is a long requested Upload Control

    Silverlight Upload Control

    The Upload Control will provide a rich UI for adding and removing files, and a progress indicator where you can suspend or resume the upload operations.

    Working with the Upload Control

    To get started, we will need to reference the DevExpress.Xpf.Controls.v10.1. The control itself lives is in the DevExpress.Xpf.Controls namespace we can reference it in XAML using the new namespace prefix xmlns:controls=http://schemas.devexpress.com/winfx/2008/xaml/controls.

    <controls:UploadControl 
    WebHandlerUri="http://localhost:62025/upload">
    </controls:UploadControl>

    The most important property that we need to set is WebHandlerUri. It should point to an HTTP handler that can process HTTP POST requests. By default, the UploadControl uses the HttpWebRequestUploadService to post data to the server, which internally uses System.Net.HttpWebRequest.

    When the data is posted to the server, HttpWebRequestUploadService will decorate the URI with following query parameters:

    • fileName: The name of the file as it appears on the client side
    • packageCount: Total number of packages that are being uploaded. (UploadControl splits the file added into packages.)
    • packageNumber: Index in into the package for that file.

    If you are using ASP.NET, you might implement an IHttpHandler to handle the upload requests. Here is a small example of an IHttpHandler that receives files from the UploadControl into a “Received Files” folder.

    public class UploadHandler : IHttpHandler {
    const string filePath = "~/Received Files";

    public bool IsReusable { get { return false; } }

    string GetServerPath(HttpServerUtility server, string fileName) {
    return server.MapPath(Path.Combine(filePath, Path.GetFileName(fileName)));
    }

    public void ProcessRequest(HttpContext context) {
    string clientFileName = Uri.UnescapeDataString(context.Request.QueryString["fileName"]);
    string serverFileName = GetServerPath(context.Server, clientFileName);

    int packageCount = int.Parse(context.Request.QueryString["packageCount"]);
    int packageNumber = int.Parse(context.Request.QueryString["packageNumber"]);

    string serverPath = Path.GetDirectoryName(serverFileName);
    if (!Directory.Exists(serverPath)) {
    Directory.CreateDirectory(serverPath);
    }

    FileMode fileMode = (File.Exists(serverFileName) && packageNumber > 0) ?
    FileMode.Append : FileMode.Create;

    using (BinaryReader reader = new BinaryReader(context.Request.InputStream)) {
    using (BinaryWriter writer = new BinaryWriter(File.Open(serverFileName, fileMode))) {
    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) != 0)
    writer.Write(buffer, 0, bytesRead);
    }
    }
    }
    }

    Cheers,

    Azret

  • Silverlight Toolbar and Menu Control - v2010 vol 1

    Continuing our DXperience v2010.1 sneak peeks, we’ll now look at the new Toolbar and Menu Library - Bars.

    Grown out of DXBars for WPF, this library is now an essential part of XPF. It will live in the DevExpress.Xpf.Core and will be used by other products in the suite where a menu UI is required.

    Silverlight/WPF Toolbar and Menu Control

    Main Menu and Toolbar Style Bars, Drag & Drop, Floating Bars and a build-in Microsoft Office Style Customization Window are all supported and the efforts to get data editors for Silverlight out first (in v2009.x) are now paying off :) W00t!

    The key concepts of the Bars library did not change in XPF. And if you are coming from WinForms, you will find the same familiar structure (well in XAML of course :)).

    <dxb:BarManager Name="barManager">
    <dxb:BarManager.Categories>
    <dxb:BarManagerCategory Name="Default" />
    </dxb:BarManager.Categories>
    <dxb:BarManager.Items>
    <dxb:BarButtonItem Name="fileNewMenuItem" CategoryName="File" Content="New" Glyph="New_16x16.png"/>
    <dxb:BarButtonItem Name="fileOpenMenuItem" CategoryName="File" Content="Open" Glyph="Open_16x16.png"/>
    <dxb:BarSubItem Name="fileMenuItem" CategoryName="Default" Content="File">
    <dxb:BarSubItem.ItemLinks>
    <dxb:BarButtonItemLink BarItemName="fileNewMenuItem"/>
    <dxb:BarButtonItemLink BarItemName="fileOpenMenuItem"/>
    <dxb:BarItemLinkSeparator></dxb:BarItemLinkSeparator>
    <dxb:BarButtonItemLink BarItemName="fileCloseMenuItem"/>
    </dxb:BarSubItem.ItemLinks>
    </dxb:BarSubItem>
    </dxb:BarManager.Items>
    <dxb:BarManager.Bars>
    <dxb:Bar Caption="Main Menu" x:Name="menuBar" IsMainMenu="True" UseWholeRow="True">
    <dxb:Bar.DockInfo>
    <dxb:BarDockInfo ContainerType="Top"/>
    </dxb:Bar.DockInfo>
    <dxb:Bar.ItemLinks>
    <dxb:BarSubItemLink BarItemName="fileMenuItem"/>
    </dxb:Bar.ItemLinks>
    </dxb:Bar>
    </dxb:BarManager.Bars>
    <!-- Main Content Here -->
    </dxb:BarManager>

    and embedding an editor…
     
    <dxb:BarEditItem Name="editFontSizeItem" CategoryName="Format" Content="Font Size:"> 
    <dxb:BarEditItem.EditSettings>
    <dxes:ComboBoxEditSettings x:Name="fontSizeSettings"/>
    </dxb:BarEditItem.EditSettings>
    </dxb:BarEditItem>

    Cheers,

    Azret

1
2
LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners