Home > Back-end >  AvaloniaUI - VIewModel can't be bound to Usercontrol
AvaloniaUI - VIewModel can't be bound to Usercontrol

Time:10-26

I'm currently working on an application with AvaloniaUI and C#.net. My application has a MainWindow that uses one ViewModel(called MainWindowViewModel) and the Window also contains two UserControls that are integrated via TabControl.

So the issue that I now have is, that I want give each UserControl its own ViewModel, so far I have created a ViewModel for one of my UserControls and also set the namespace to it in the axaml-File of my Control. I've set the DataContext also, but the ViewModel is never been loaded.

As follows here's the source code of my MainWindow, the UserControl und the ViewModel of my UserControl:

MainWindow.axaml

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:MyApp.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:views ="clr-namespace:MyApp.Views"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="MyApp.Views.MainWindow"
    WindowStartupLocation="CenterScreen"
        Icon="/Assets/Programmicon.png"
        Title="{Binding WindowTitle}" CanResize="False" >
    <Design.DataContext>
        <vm:MainWindowViewModel/>
    </Design.DataContext>
        <Window.Styles>
            <Style Selector="TabItem">
                <Setter Property="FontSize" Value="16"/>
                <Setter Property="FontWeight" Value="Bold"/>
                <Setter Property="Height" Value="34"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="Background" Value="#148198"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="Margin" Value="0 0 0 0"/>
                <Setter Property="Padding" Value="10 0"/>
            </Style>
            <Style Selector="TabControl WrapPanel">
                <Setter Property="Background" Value="#148198"/>
            </Style>
            <Style Selector="TabItem:selected">
                <Setter Property="Background" Value="White"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="Margin" Value="0 0 0 0"/>
                <Setter Property="Padding" Value="10 0"/>
            </Style>
        </Window.Styles>
        <Grid>
        <TabControl Name="tabMenu" Background="White">
            <TabItem Header="Import" VerticalContentAlignment="Center" >
                <views:ImportView/>
            </TabItem>
            <TabItem Header="Einstellungen" VerticalContentAlignment="Center">
                <views:SettingsView/>
            </TabItem>
        </TabControl>
            <Label Name="lblErrorInfo" Content="" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ZIndex="10" Background="Red" Foreground="White" FontSize="34" FontWeight="Bold" IsVisible="false"></Label>
    </Grid>
</Window>

SettingsView.axaml

<UserControl xmlns="https://github.com/avaloniaui"
             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:vm="using:MyApp.ViewModels"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="MyApp.Views.SettingsView">
    <this.DataContext>
        <vm:SettingsViewModel/>
    </this.DataContext>
        <DataGrid Name="gEventlog" Items="{Binding EventlogData}" AutoGenerateColumns="False" CanUserResizeColumns="False" CanUserReorderColumns="False" Background="LightGray" CanUserSortColumns="True" Canvas.Top="20" Width="1024" Height="626" GridLinesVisibility="All" IsReadOnly="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" AlternatingRowBackground="Azure">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID"/>
                    <DataGridTextColumn Header="Zeitstempel"/>
                    <DataGridTextColumn Header="Event-Typ"/>
                    <DataGridTextColumn Header="Benutzer"/>
                    <DataGridTextColumn Width="563" Header="Fehlermeldung"/>
                    <DataGridTextColumn Header="Funktion"/>
                </DataGrid.Columns>
        </DataGrid>
</UserControl>

SettingsViewModel.cs

using MyApp.Classes;
using Microsoft.Data.Sqlite;
using System;
using System.Data;

namespace MyApp.ViewModels
{
    public class SettingsViewModel : ViewModelBase
    {
        // The appconfig class
        private readonly AppConfiguration _appConfig;
        // The utils class
        private readonly Utils _utils;
        // The eventlog class
        private readonly Eventlog _event;

        private string _importFilesPath;

        // The data of the eventlog-grid
        private DataView _eventlogData;

        public DataView EventlogData
        {
            get { return _eventlogData; }
            set
            {
                if (_eventlogData == value)
                {
                    return;
                }

                _eventlogData = value;
            }
        }

        public string ImportFilesPath
        {
            get { return _importFilesPath; }
            set
            {
                if (_importFilesPath == value)
                {
                    return;
                }

                _importFilesPath = value;
            }
        }

        public SettingsViewModel()
        { 
            // Initialize the members
            _appConfig = new AppConfiguration();    
            _utils = new Utils();
            _event = new Eventlog();    
            _eventlogData = new DataView();
            _importFilesPath = "";

            this.InitializeGUI();
        }
        
        private void InitializeGUI()
        {
            //Fill the eventlog grid
            LoadEventlog();

            _importFilesPath = _appConfig.ImportPath;
        }
    }
}

So my question is, how can I connect my UserControl with the corresponding ViewModel? I'm new to AvaloniaUI, but coming from WPF where that approach (Give every UserControl an own ViewModel) works. Maybe I am overseeing some essential things.

Thanks in advance for every answer

CodePudding user response:

If you have created your application using MVVM Avalonia template you should have a file called ViewLocator which already "connects" the view model with the corresponding view. Then if you want to display your settings in the main window you can add a property to the MainWindowViewModel:

public SettingsViewModel Settings { get; }

And bind it in the MainWindow

<ContentControl Content="{Binding Settings}"/>
  • Related