EzDev.org

Catel

Catel - An application development platform


How to unitest a call to IUIVisualizerService has been made

I am trying to verify that a call to IUiVisualizerService.ShowAsync(dialog) has been made. I am using machine specifications as my testing framework with FakeItEasy. Any insight would be helpful.

thanks


Source: (StackOverflow)

How To Fix Missing Assembly Reference 'Microsoft.Xaml.Interactivity.dll' in Windows Store App Solution?

I have a Windows Store App solution which worked fine up until I installed Nuget Packages and Extentions from Catel. Now when I build the solution I get about 12 build errors with the following description originating from my startup project's .csproj file:

Cannot resolve Assembly or Windows Metadata file 'Microsoft.Xaml.Interactivity.dll'

One would think, remove then add the reference again but you cannot manage the framework's assembly references.


Source: (StackOverflow)

MahApps and Catel MVVM

Is it possible to combine the MahApps visual style, including the style of the window, but the View and ViewModel from Catel? All of they require inherit window (View)


Source: (StackOverflow)

How to switch multiple views in WPF MVVM Catel application?

In MS VS 2015 Professional I develop C# WPF MVVM application using Catel as MVVM framework. My problem is I don't know how to realize switching among multiple views in one window using buttons. Below I briefly describe my application. The MainWindow has three buttons

<catel:Window x:Class="FlowmeterConfigurator.Views.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:catel="http://catel.codeplex.com"
          ResizeMode="CanResize">

     <catel:StackGrid x:Name="LayoutRoot">
        <catel:StackGrid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto"/>
        </catel:StackGrid.RowDefinitions>

        <ToolBar>
            <Button Name="btnConnectDisconnect" Content="Connect/Disconnect"/>
            <Button Name="btnFieldSettings" Content="Field Settings"/>
            <Button Name="btnCalibration" Content="Flowmeter Calibration"/>
        </ToolBar>
    </catel:StackGrid>
</catel:Window>

Application MainWindow has a ViewModel. For brevity I don't show it here. In addition to MainWindow there are three views in my application: ConnectDisconnectView, CalibrationView and FieldSettingsView. For brevity I show here only one of them (FieldSettingsView) because all of others are created in the same manner on the base of catel:UserControl.

<catel:UserControl x:Class="FlowmeterConfigurator.Views.FieldSettingsView"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:catel="http://catel.codeplex.com">

    <catel:StackGrid>
        <catel:StackGrid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </catel:StackGrid.RowDefinitions>
        <catel:StackGrid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </catel:StackGrid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="Flowmeter Serial Number"/>
        <TextBox Name="SerialNumber" Grid.Row="0" Grid.Column="1"/>
    </catel:StackGrid>

</catel:UserControl>

Each of these views has a Model. I show here only one of these Models because all of them created in the same manner.

using Catel.Data;
namespace FlowmeterConfigurator.Models
{
    /// <summary>
    /// Field Settings Model.
    /// </summary>
    public class FieldSettingsModel : SavableModelBase<FieldSettingsModel>
    {
        /// <summary>
        /// Returns flowmeter serial number.
        /// </summary>
        public string SerialNumber
        {
            get { return GetValue<string>(SerialNumberProperty); }
            set { SetValue(SerialNumberProperty, value); }
        }

    /// <summary>
    /// Register SerialNumber property.
    /// </summary>
    public static readonly PropertyData SerialNumberProperty = RegisterProperty("SerialNumber", typeof(string), null);
    }
}

Each of these views has a ViewModel. I show here only one of these ViewModels because all of them created in the same manner.

using Catel;
using Catel.Data;
using Catel.MVVM;
using FlowmeterConfigurator.Models;

namespace FlowmeterConfigurator.ViewModels
{
    /// <summary>
    /// Field settings ViewModel.
    /// </summary>
    public class FieldSettingsViewModel : ViewModelBase
    {
        /// <summary>
        /// Creates a FieldSettingsViewModel instance.
        /// </summary>
        /// <param name="fieldSettingsModel">Field settings Model.</param>
        public FieldSettingsViewModel(FieldSettingsModel fieldSettingsModel)
        {
            Argument.IsNotNull(() => fieldSettingsModel);
            FieldSettings = fieldSettingsModel;
        }

        /// <summary>
        /// Returns or sets Field Settings Model.
        /// </summary>
        [Model]
        public FieldSettingsModel FieldSettings
        {
            get { return GetValue<FieldSettingsModel>(FieldSettingsProperty); }
            set { SetValue(FieldSettingsProperty, value); }
        }

        /// <summary>
        /// Here I register FieldSettings property.
        /// </summary>
        public static readonly PropertyData FieldSettingsProperty = RegisterProperty("FieldSettings", typeof(FieldSettingsModel), null);

        /// <summary>
        /// Returns or sets flowmeter serial number.
        /// </summary>
        [ViewModelToModel("FieldSettings")]
        public string SerialNumber
        {
            get { return GetValue<string>(SerialNumberProperty); }
            set { SetValue(SerialNumberProperty, value); }
        }

        /// <summary>
        /// Here I register SerialNumber property.
        /// </summary>
        public static readonly PropertyData SerialNumberProperty = RegisterProperty("SerialNumber", typeof(string), null);
    }
}

Directly after my application loading, ConnectDisconnectView must be displayed. And then user can switch the views at will using the buttons on MainWindow toolbar. The switching among the Views must be in the following manner: if (for example) the current displayed view is "ConnectDisconnectView" and user presses "Field Settings" button then "ConnectDisconnectView" view must disappear from MainWindow and "FieldSettingsView" view must appear and must be displayed in MainWindow. And so on. That is when pressed appropriate button in MainWindow toolbar (for example "Flowmeter Calibration") the appropriate view (CalibrationView) must be displayed in MainWindow and other views must not be displayed. How can I realize this capability in my application? Your help will be appreciate highly.

P.S. Of course as you see the number and content of Views are reduced here for brevity and clarity. In real world the number of Views in my application is about 20 - 25 and they must contain complex graphics and table information.


Source: (StackOverflow)

How would I use Autofac as the primary container in Catel?

Is there a way I can use Autofac as my primary container for Catel? I've seen that there is support for Unity, Ninject, MEF, Windsor, and Unity, but there is no mention of Autofac integration.


Source: (StackOverflow)

How to migrate from Catel project to Orchestra + MahApps? (.NET 4.0)

I have a Catel project, using various Catel controls and classes, how do I migrate/update it to Orchestra (MahApps)?


Source: (StackOverflow)

Catel's AsynchronousCommand correct usage

I've to call an async Task using a command. I tought that AsynchronousCommand would have done the trick but it accepts an Action as method so I've to use something as

public async void Something(object args)

would it be supposed to accept a Task on Command's definition?

UPDATE #1

Used TaskCommand as suggested by @Geert


Source: (StackOverflow)

Collection of ViewModels in Catel

I have a View with several DataTemplates. Each DataTemplate has a View and ViewModel like so:

<DataTemplate DataType="{x:Type viewModels:exampleViewModel}">
    <AdornerDecorator>
        <ScrollViewer>
            <views:exampleView />
        </ScrollViewer>
    </AdornerDecorator>
</DataTemplate>

Then I have a TabControl which is bound to a DataContext.

In the DataContext, there is a Collection which has a list of all the different viewModels referenced by the DataTemplates:

<TabControl
    DataContext="{Binding}"
    ItemsSource="{Binding Collection, Mode=OneWay}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock
                Text="{Binding}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

Obviously there is one 'main' ViewModel for the View that contains the TabControl.

This works pretty well, creating TabItems for me for each item in the Collection and also setting the content of each page.

I now want to move this over to Catel but have no idea on where to begin because (and correct me if I'm wrong) :

  1. I now should not have any reference to any other ViewModel within any ViewModel and

  2. Catel automatically will link up my Views and ViewModels for me.

Any suggestions?


Source: (StackOverflow)

Catel async await command in ShowDialog - Deadlock

Using a library –°atel latest version (3.8.1 beta).

How can I use TAP method from dialog window?

Example. In main ViewModel calling a method

private bool ShowDialogWindow()
{
    var typeFactory = TypeFactory.Default ;
    var vm = typeFactory.CreateInstanceWithParametersAndAutoCompletion<LoginWindowViewModel>();
    return _uiVisualizerService.ShowDialog(vm) ?? false;
}

In LoginWindowViewModel I have Command (also try AsynchronousCommand) which is called method

public async Task<int> Test(string login, string password)
{
     var a = await Task<int>.Factory.StartNew(() =>
     {
         using (var uow = new UnitOfWork<TSDbContext>())
         {
             var userRep = uow.GetRepository<IUserRepository>();
             userRep.GetAll();
             return 5;
         }
     });
     a++;
     return a;
}

I got the results from awaited method only when close the dialog window. Lock appears on line

var uow = new UnitOfWork()

ConfigureAwait(false) - does not help solve the problem

When I delete UnitOfWork - method works

When I Change Method Code to This var d = TypeFactory.Default.CreateInstanceWithParameters(); return 5;

Blocking is also reproduced on the line TypeFactory...

Depending on the services Catel are not allowed in the dialog box


Source: (StackOverflow)

Getting DialogResult using uiVisualizerservice.Show

I was porting a modal dialog to a non-modal one.

My problem is: uiCompletedEventArgs.Result is null.

I've seen having the debug exception enabled that the following exception is thrown "DialogResult can be set only after Window is created and shown as dialog."

Here is a snippet of my code

 var viewmodel = viewModelFactory.CreateViewModel<GenericViewModel>(someIds);

       uiVisualizerService.Show(viewmodel, CompletedProc);
    }

    private async void CompletedProc(object sender, UICompletedEventArgs uiCompletedEventArgs)
    {
        if (uiCompletedEventArgs.Result.HasValue && uiCompletedEventArgs.Result.Value) //here's null
        { ... }

How can I tell if a user clicked Yes or Cancel button?

Thanks for your advice.


Source: (StackOverflow)

Catel MVVM Structure

I have a simple WPF Application and I used Catel (3.5) framework for using MVVM. The Default structure for Catel in visual studio is:

Solution:
  Project:
    FolderView
    FolderViewModel
    FolderModel

I want to change the structure to

Solution:
  ProjectView
  ProjectViewModel
  ProjectModel

in this way I completely separate M-VM-V and I add reference.

I Understand that Catel scans the project automatically to find the Viewmodels if the naming convention are respected.

I can not make this work on the second structure, any advice will be pretreated.

EDIT 1: I have added the following code in App.xaml.cs

var viewModelLocator = ServiceLocator.Default.ResolveType<IViewModelLocator>();
viewModelLocator.NamingConventions.Add("CatelV2ViewModel.ViewModels.[VW]ViewModel");

This does not work for me, and I have No Idea why. Im sure that My assembly name is correct AND I end my class name with ViewModel.

EDIT 2: The application Works if I add the following code:

viewModelLocator.Register(typeof(MainWindow), typeof(MainWindowViewModel));

But I still want to know why it dosent work when I add a NamingConvention.


Source: (StackOverflow)

Catel PersonApplication example

Currently studying Catel.

In the PersonApplication of the Catel.Examples - specifically, the PersonWindow.xaml: the design time data is not being shown within the Visual Studio Designer.

In the code of the PersonViewModel, the public properties are commented out. Apparently this is because the code is using Fody to create the Model properties at runtime. So, I uncommented the public properties assuming that the Visual Studio Designer requires Public Properties to show designtime data in the Designer. Still, the designtime data of the DesignPersonViewModel does not show in the designer.

The application runs correctly at runtime. There are no messages on Building to indicate an issue within the XAML or the code. The XAML code declaring the designtime datacontext is correct:

d:DataContext="{d:DesignInstance ViewModels:DesignPersonViewModel,
                                 IsDesignTimeCreatable=True}"

Any explanation for why the designtime data does not show in the Designer?

I am using Visual Studio 2015.


Source: (StackOverflow)

Setting DataContext in Catel with WPF

So I've started looking at the Catel MVVM framework and it looks like it will solve a couple of problems I have encountered, but I have one really silly issue. I think I'm just missing something small.

I took one of my smaller WPF projects to switch over the Catel as a way for me to learn it. I have a simple 'Player Registration' form, with fields like name and surname. I recreated my original view model by using the vm codesnippet and all is good, all the properties and attributes I've set up as I've read in the documentation.

I then changed the UserControl I used for 'Player Registration' (PlayerRegistrationView) to a catel:UserControl. I placed PlayerRegistrationView on a standard WPF Window (nothing else, just a xmlns for the View and the view as the only content on the window, no attributes)

But here is my problem:

I have a MainWindow with a button on to open the Window for the player registration. The on-click event simply is this:

private void ButtonPlayerClick(object sender, RoutedEventArgs e)
    {
       var playerRegistration = new PlayerRegistrationDialog
            {
                Owner = this,
                DataContext = new PlayerRegistrationViewModel(),
            };

       playerRegistration.Show();
    }

Running my program and then clicking on the button results in an NotSupportedException on my PlayerRegistrationView: The view model of the view could not be resolved. Use either the GetViewModelType() method or IViewModelLocator

I tried making the ViewModel a static resource on the window and setting the datacontext there, but it produces the same error.

I am at a loss. What have I missed?

Thanks


Source: (StackOverflow)

Catel ViewModelToModel not linking

I have a simple ViewModel which has two Models. So it looks like this:

public class ConnectionItemSelectorViewModel : ViewModelBase {
    ...

    #region AvailableConnectionsModel

    // Model Nr. 1
    [Model]
    public ConnectionList AvailableConnectionsModel
    {
        get { return GetValue<ConnectionList>(AvailableConnectionsModelProperty); }
        set { SetValue(AvailableConnectionsModelProperty, value); }
    }

    public static readonly PropertyData AvailableConnectionsModelProperty = RegisterProperty(nameof(AvailableConnectionsModel), typeof(ConnectionList), () => new ConnectionList());

    #endregion

    #region SelectedConnectionsModel

    // Model Nr. 2
    [Model]
    public ConnectionList SelectedConnectionsModel
    {
        get { return GetValue<ConnectionList>(SelectedConnectionsModelProperty); }
        set { SetValue(SelectedConnectionsModelProperty, value); }
    }

    public static readonly PropertyData SelectedConnectionsModelProperty = RegisterProperty(nameof(SelectedConnectionsModel), typeof(ConnectionList), () => new ConnectionList());

    #endregion

    ...
}

ConnectionList extends ModelBase so I can use the [Model]-Attribute several times.

Now I want to expose the properties of the Model to the ViewModel:

public class ConnectionItemSelectorViewModel : ViewModelBase {
    ...
    // init Model properties

    #region AvailableConnections

    // Using a unique name for the property in the ViewModel
    // but linking to the "correct" property in the Model by its name
    [ViewModelToModel(nameof(AvailableConnectionsModel), nameof(ConnectionList.Connections))]
    public ObservableCollection<ConnectionItem> AvailableConnections
    {
        get { return GetValue<ObservableCollection<ConnectionItem>>(AvailableConnectionsProperty); }
        set { SetValue(AvailableConnectionsProperty, value); }
    }

    public static readonly PropertyData AvailableConnectionsProperty = RegisterProperty(nameof(AvailableConnections), typeof(ObservableCollection<ConnectionItem>), () => null);

    #endregion

    // linking other properties to the models
    ...
}

The problem is that the linking doesn't work. So after initialization the property AvailableConnections (and the others also) are still null, though the Model itself is initialized correctly.

Am I missing something or isn't this possible at all?

thx in advance!


Source: (StackOverflow)

Binding from within a ResourceDictionary in a Catel WPF UserControl

I am converting some of the views and view models of our WPF application over to Catel, as a proof-of-concept.

One of the user controls doesn't seem to be correctly binding to the view model at runtime. I think I understand why that is, but would like to get some feedback on what the best remedy is.

The code

I have a simple view whose model is actually an ObservableCollection:

PersonTable.xaml

Key things to note: I'm using a CollectionViewSource that wraps the main collection that the DataGrid binds to. This is so I can keep the grid auto-sorted.

<catel:UserControl x:Class="MyApp.PersonTable"
             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:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
             xmlns:catel="http://catel.codeplex.com"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="200" d:DataContext="{DynamicResource DesignTimeViewModel}">
    <UserControl.Resources>
        <ResourceDictionary>
            <CollectionViewSource Source="{Binding PersonItems}" x:Key="PersonItemsSource">
                <CollectionViewSource.SortDescriptions>
                    <scm:SortDescription PropertyName="DOB" Direction="Descending" />
                </CollectionViewSource.SortDescriptions>
            </CollectionViewSource>

            <ui:DesignPersonViewModel x:Key="DesignTimeViewModel" />
        </ResourceDictionary>
    </UserControl.Resources>

    <Grid>
        <DataGrid ItemsSource="{Binding Source={StaticResource PersonItemsSource}}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name, Mode=TwoWay}" 
                                    Header="Name" Width="90"
                                    ElementStyle="{StaticResource CellRightAlign}" />
                <!-- etc..... -->
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</catel:UserControl>

PersonTableViewModel.cs

The view model accepts the model in the constructor:

using Catel.MVVM;

public class PersonTableViewModel : ViewModelBase
{
    public PersonTableViewModel(ObservableCollection<Person> personItems)
    {
        this.PersonItems = personItems
    }

    public ObservableCollection<Person> PersonItems
    {
        get { return GetValue<ObservableCollection<Person>>(PersonItemsProperty); }
        set { SetValue(PersonItemsProperty, value); }
    }

    public static PropertyData PersonItemsProperty = 
        RegisterProperty("PersonItems", typeof(ObservableCollection<Person>), () => new ObservableCollection<PersonItems>());
}

The Problem

At runtime, no items are populated in the grid. Although at design time, the design view model does correctly populate the grid in the design view.

Am I right about the source of the problem? I believe it's that the control that is bound to the PersonItems property is not part of the visual tree, but is embedded in a control-level resource dictionary? Based on my reading of the documentation, specifically the article UserControl - Under the hood, it seems that the Catel UserControl class injects the view model as a hidden inner DataContext inside the visual tree only, but my {Binding} inside a resource dictionary item might get left out in the cold.

Assuming I'm right, what's the best remedy?

If I'm right about the above, then I can think of a few possible remedies, none of which seem perfect. I would love to know what the accepted best practice is to remedy this situation.

  • Move the CollectionViewSource to the code behind; expose it as a dependency property. I don't love this option because I can't then configure it in XAML.
  • Move the CollectionViewSource to the view model. I really don't love this one; putting WPF components in the view model breaks MVVM.
  • Bind the CollectionViewSource to the original DataContext (i.e. the model). The problem there is that then the design-time view model would not bind correctly.

    <CollectionViewSource Source="{Binding}" ..... >
    
  • Expose a dependency property from the code-behind that is bound to the view model. UPDATE: this works at runtime, but now fails at design time (in that the grid does not contain the test data.)

    ---- PersonTable.xaml.cs ----
    
    [ViewToViewModel(MappingType = ViewToViewModelMappingType.ViewModelToView]
    public ObservableCollection<PersonItem> PersonItems { get { ... } }
    
    ---- PersonTable.xaml ----
    
    <CollectionViewSource Source="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type PersonTable}}, Path=PersonItems}" ...... >
    

Source: (StackOverflow)