0 Comments

ASP.NET Core ViewComponents usually come in pairs: There’s the class which inherits ViewComponent and there’s the Razor view which is returned by the class:

image

In most of the situations the ViewComponent runs some logic and then returns the view:

    public class MyTest : ViewComponent
    {
        public Task<IViewComponentResult> InvokeAsync(string content)
        {
            return Task.FromResult<IViewComponentResult>(View("Default"));
        }
    }

But what if you need to return the view only in some cases based on the ViewComponent’s parameters or because of some other validation? In these situation you can skip returning the view by returning empty content instead:

    public class MyTest : ViewComponent
    {
        public Task<IViewComponentResult> InvokeAsync(string content)
        {

            if (string.IsNullOrWhiteSpace(content))
            {
                return Task.FromResult<IViewComponentResult>(Content(string.Empty));
            }

            return Task.FromResult<IViewComponentResult>(View("Default", content));
        }
    }
 

0 Comments
  •   Posted in: 
  • UWP

UWP.MDI is a library for building MDI applications in UWP. In the introduction post I mentioned that UWP.MDI has two goals:

  1. To provide comprehensive MDI support for UWP applications.
  2. To provide MDI support in such a way that those familiar with Windows Forms' MDI support feel at home.

One goal was missing from that list: Making UWP the best platform for building MDI applications. That means that when using UWP.MDI, we should be able to reap the benefits which UWP has over Windows Forms: XAML, data binding and the MVVM paradigm.

MVVM and UWP.MDI

To see how UWP.MDI and MVVM play together, there’s now a new sample in the repo: https://github.com/mikoskinen/UWP.MDI/tree/master/samples/UWP.MDI.MVVM

The sample doesn’t use any MVVM framework to make it clean. It contains a ViewModelLocator which is used to hook forms and view models together but other than that, it’s straight forward.

The sample contains the Main page (MDI Container) and two forms (Customers, Invoices). Each of these has a corresponding view model. For example here’s the CustomerViewModel which is bind against the form:

        public CustomerViewModel()
        {
            var customers = new ObservableCollection<Customer>();

            var names = new List<Tuple<string, string>>
            {
                Tuple.Create("Noel", "Hess"),
                Tuple.Create("Silver", "Holland"),
                Tuple.Create("Rudy", "Phillips"),
                Tuple.Create("Skylar", "Cabrera"),
                Tuple.Create("Blair", "Kirby"),
            };

            for (int i = 0; i < names.Count; i++)
            {
                var id = i + 1;
                var name = names[i];
                var customer = new Customer(id, name.Item1, name.Item2);
                customers.Add(customer);
            }

            Customers = customers;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

The form itself hooks up with the view model through the ViewModelLocator:

<UserControl
    x:Class="UWP.MDI.Samples.MVVM.Customers.CustomerForm"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:grid="using:Telerik.UI.Xaml.Controls.Grid"
    xmlns:controls="using:UWP.MDI.Controls"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"
    Width="450"
    Height="400" controls:FormProperties.Text="Customers" DataContext="{Binding CustomerViewModel, Source={StaticResource ViewModelLocator}}">

    <Grid>

        <Grid>
            <grid:RadDataGrid x:Name="DataGrid" ItemsSource="{Binding Customers}"/>
        </Grid>
    </Grid>
</UserControl>

We use commands to display the forms through the MainPageViewModel:

    public class MainPageViewModel
    {
        public ICommand ShowCustomersCommand { get; set; }
        public ICommand ShowInvoicesCommand { get; set; }
        public ICommand ExitCommand { get; set; }

        public MainPageViewModel()
        {
            ShowCustomersCommand = new RelayCommand(() =>
            {
                var frm = new Customers.CustomerForm();
                frm.Show();
            });

            ShowInvoicesCommand = new RelayCommand(() =>
            {
                var frm = new Invoices.InvoiceForm();
                frm.Show();
            });

            ExitCommand = new RelayCommand(() =>
            {
                Application.Current.Exit();
            });
        }
    }

All in all, straight forward code if you’re familiar with MVVM.

Coming soon

A sample which uses Caliburn.Micro is coming soon. Caliburn.Micro is a full blown MVVM framework and creating a sample for it is a good way to make sure that UWP.MDI has the required extensions points to make it work correctly with all the MVVM frameworks out there.

0 Comments

imageLast week I introduced UWP.MDI, a new library for building MDI applications in UWP.

The open source library has been updated this week to support automatic arrangement of child windows. The library now contains three built-in layouts:

Cascade

image

Tile vertical

image

Tile horizontal

image

Usage

To apply layout, call MDIContainer.LayoutMdi(desired layout). Built-in layouts are available from LayoutMdi:

        private void CascadeMenuItem_OnClick(object sender, RoutedEventArgs e)
        {
            Mdi.LayoutMdi(MdiLayout.Cascade);
        }

        private void TileVerticalMenuItem_OnClick(object sender, RoutedEventArgs e)
        {
            Mdi.LayoutMdi(MdiLayout.TileVertical);
        }

        private void TileHorizontalMenuItem_OnClick(object sender, RoutedEventArgs e)
        {
            Mdi.LayoutMdi(MdiLayout.TileHorizontal);
        }

Custom layouts

You can implement custom MDI layouts by inheriting abstract class MdiLayout and implementing the RunLayout-method.

Good starting point for an example is Cascade layout.

Note

Layouts are not continuous. Meaning, they only arrange windows when run, after which user can again move and resize windows as they desire.

Sample

Repository contains a new “samples”-folder which currently includes two samples: Getting started and Layouts. You can check out the layouts-sample for more concrete guidance.

NuGet

The layout support isn’t included in the current 1.0.0.1 package but it will be included in version 1.1.0.0, which is coming out later this week.

You can get the latest bits from GitHub and start working with the feature.

0 Comments

UWP.MDI_faster

UWP.MDI is a new library which provides MDI (Multiple document interface) support for UWP applications. The library is completely open source and available with MIT license.

Background

MDI (Multiple Document Interface) was popular user interface paradigm in Windows Forms era. MDI allows one window to host multiple child windows. Each window can be resized and moved around.

When WPF was released, it didn't contain support for MDI interfaces and the situation didn't change when WinRT and UWP were released.

UWP.MDI has two targets:

  1. To provide comprehensive MDI support for UWP applications.
  2. To provide MDI support in such a way that those familiar with Windows Forms' MDI support feel at home.

Getting started

Getting started with UWP.MDI aims to be simple:

  1. Create a blank uwp application
  2. Add MDIContainer into the MainForm
  3. Add UserControl
  4. Show UserControl by creating a new instance of it and calling MyUserControl.Show()

The easiest way to get learn more is to clone the project repository (https://github.com/mikoskinen/UWP.MDI) and to launch the sample application. The sample contains the MDI container and couple child windows.

Known issues

The library has few known issues. Main thing is making sure that everything works nicely with your MVVM framework of choice. The UWP.MDI library is implemented in such a way that you can continue using for example Caliburn.Micro, but there’s currently no available sample for that.

Links

UWP.MDI is available from GitHub: https://github.com/mikoskinen/UWP.MDI

0 Comments

I released NSQLFormatter few years ago (actually it’s more than few years ago, back in 2011.). As a reminder, NSQLFormatter is "an open-source SQL Beautifier written with C#".

In 2015 the library was released as a Portable Class Libray. There's now a new version which targets .NET Standard 1.3. This version is supported by about every currently supported .NET platform, including .NET Core, Mono and .NET Framework 4.6.1.

Let me know if you encounter any issues with the project.

GitHub: https://github.com/mikoskinen/NSQLFormatter-dotnet

NuGet: https://www.nuget.org/packages/NSQLFormatter/