简体   繁体   中英

Binding to an enum inside a child view model combobox object is not renders on UI

I have a Parent ViewModel which contains a child view model object inside with some enum,

When I open the UI I see that the enum value not renders as expected from the RaisePropertyChanged event on first time loading, however, after setting a value from the UI the value changes and renders as expected.

Parent VM xaml

<UserControl x:Class="RemoteDebugger.App.Views.ConfigurationControl" 
        d:DataContext="{d:DesignInstance viewModels:ConfigurationViewModel}">
        <Grid>
            //Some properties...
            <local:ProjectEditor Grid.Row="5" Grid.Column="1" BorderBrush="#FFCFCBCB" BorderThickness="0,1,0,1"  Grid.ColumnSpan="3" DataContext="{Binding MainProject,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ></local:ProjectEditor>
        </Grid>

Parent VM cs

using RemoteDebugger.App.Utils;
using System.Collections.Generic;
using System.IO;
using System.Windows.Input;
using Microsoft.Win32;
using RemoteDebugger.Model;
using RemoteDebugger.Model.DataStructures;

namespace RemoteDebugger.App.ViewModels
{
public class ConfigurationViewModel : BaseViewModel
{
    private ICommand _saveConfiguration;
    private ICommand _loadConfiguration;

    private Configuration _configuration;
    private ProjectViewModel _mainProject;
    private ExtraProjectsViewModel _extraProjects;


    public ConfigurationViewModel()
    {
        _configuration = RemoteDebuggerManager.Instance.Configuration;
        _mainProject = new ProjectViewModel(_configuration.MainProject);
        _extraProjects = new ExtraProjectsViewModel(_configuration.ExtraProjectsToCopy);
    }

    public ICommand SaveConfiguration
    {
        get
        {
            return _saveConfiguration ??= new Command(o =>
            {
                _configuration.MainProject = _mainProject.Project;
                _configuration.ExtraProjectsToCopy = _extraProjects.Projects;
                RemoteDebuggerManager.Instance.SaveConfigurations();
            });

        }
    }

    public ICommand LoadConfiguration
    {
        get
        {
            return _loadConfiguration ??= new Command(o =>
            {
                var fd = new OpenFileDialog
                {
                    Multiselect = false,
                    Filter = "XML Files (*.xml)|*.xml",
                    InitialDirectory = ConfigurationHandler.ConfigurationFolder
                };
                var path = fd.ShowDialog();
                if (path == null || !File.Exists(fd.FileName)) 
                    return;
                _configuration = RemoteDebuggerManager.Instance.LoadConfigurations(fd.FileName);

                UpdateView();
            });

        }
    }

    private void UpdateView()
    {
        OsBits = _configuration.OsBits;
        VisualStudioVersion = _configuration.VisualStudioVersion;
        CopyExtraPaths = _configuration.CopyExtraPaths;
        Ip = _configuration.ControllerIp;
        _mainProject.Project = _configuration.MainProject;
        _extraProjects.Projects = _configuration.ExtraProjectsToCopy;
    }
    public string VisualStudioVersion
    {
        get => _configuration.VisualStudioVersion;
        set
        {
            _configuration.VisualStudioVersion = value;
            RaisePropertyChanged(nameof(VisualStudioVersion));
        }
    }

    public string OsBits
    {
        get => _configuration.OsBits;
        set
        {
            _configuration.OsBits = value;
            RaisePropertyChanged(nameof(OsBits));
        }
    }

    public string Ip
    {
        get => _configuration.ControllerIp;
        set
        {
            _configuration.ControllerIp = value;
            RaisePropertyChanged(nameof(Ip));
        }
    }
    public string WaitForDebugFileDestination
    {
        get => _configuration.WaitForDebugFileDestination;
        set
        {
            _configuration.WaitForDebugFileDestination = value;
            RaisePropertyChanged(nameof(WaitForDebugFileDestination));
        }
    }
    public bool CopyExtraPaths
    {
        get => _configuration.CopyExtraPaths;
        set
        {
            _configuration.CopyExtraPaths = value;
            RaisePropertyChanged(nameof(CopyExtraPaths));
        }
    }

    public ProjectViewModel MainProject
    {
        get => _mainProject;
        set
        {
            _mainProject = value;
            RaisePropertyChanged(nameof(MainProject));
        }
    }
    public ExtraProjectsViewModel ExtraProjects
    {
        get => _extraProjects;
        set
        {
            _extraProjects = value;
            RaisePropertyChanged(nameof(ExtraProjects));
        }
    }
    public List<string> VisualStudioSupportedVersions => EnvironmentValues.VisualStudioVersions;
    public List<string> OsBitsTypes => EnvironmentValues.OsBits;
}

}

Child VM xaml

<UserControl x:Class="RemoteDebugger.App.Views.ProjectEditor"
         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:viewModels="clr-namespace:RemoteDebugger.App.ViewModels"
         xmlns:local="clr-namespace:RemoteDebugger.App.Views"
         mc:Ignorable="d" 
         d:DataContext="{d:DesignInstance viewModels:ProjectViewModel}"
         >
        <Grid>
    <Grid.RowDefinitions>
         ...
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        ...
    </Grid.ColumnDefinitions>
    <ComboBox  Grid.Row ="1" Grid.Column="1" ItemsSource="{Binding ProjectTypes}" VerticalAlignment="Center" SelectedItem="{Binding ProjectType,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" FontSize="14" />
    <TextBlock Grid.Row ="1" Grid.Column="0" Text="Project type" TextWrapping="Wrap"/>
    <TextBlock Grid.Row ="5" Grid.Column="0" Text="Local project path" VerticalAlignment="Center"  TextWrapping="Wrap"/>
    <TextBox   Grid.Row ="5" Grid.Column="1" Height="30" Text="{Binding LocalDllDirRoot,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
    <TextBlock Grid.Row ="7" Grid.Column="0" Text="Remote project path" VerticalAlignment="Center"  TextWrapping="Wrap"/>
    <TextBox   Grid.Row ="7" Grid.Column="1" Height="30" Text="{Binding RemoteDllDirRoot,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
    <TextBlock Grid.Row ="9" Grid.Column="0" Text="Arguments" VerticalAlignment="Center"  TextWrapping="Wrap"/>
    <TextBox   Grid.Row ="9" Grid.Column="1" Height="30" Text="{Binding Arguments,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
    <TextBlock Grid.Row ="3" Grid.Column="0" Text="Executable name" VerticalAlignment="Center" TextWrapping="Wrap"/>
    <TextBox   Grid.Row ="3" Grid.Column="1" Height="30" Text="{Binding ExecutableName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</Grid>

Child VM cs file

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using IntelGenericUIFramework.Common;
using RemoteDebugger.Model.DataStructures;

namespace RemoteDebugger.App.ViewModels
{
    public class ProjectViewModel : BaseViewModel,ICloneable
    {
        private ProjectDescriptor _project;
        public ProjectViewModel()
        {
            _project = new ProjectDescriptor();
        }
        public ProjectViewModel(ProjectDescriptor projectDescriptor)
        {
            _project = projectDescriptor == null ? new ProjectDescriptor() : 
            (ProjectDescriptor)projectDescriptor.Clone() ;
            UpdateProperties();
        }

    private void UpdateProperties()
    {
        foreach (var prop in this.GetType().GetProperties())
        {
            RaisePropertyChanged(nameof(prop.Name));
        }
    }

    #region Main project values
    public string LocalDllDirRoot
    {
        get => _project.LocalDllDirRoot;
        set
        {
            Project.LocalDllDirRoot = value;
            RaisePropertyChanged(nameof(LocalDllDirRoot));
            RaisePropertyChanged(nameof(Project));

        }
    }
    public string RemoteDllDirRoot
    {
        get => _project.RemoteDllDirRoot;
        set
        {
            _project.RemoteDllDirRoot = value;
            RaisePropertyChanged(nameof(RemoteDllDirRoot));
            RaisePropertyChanged(nameof(Project));

        }
    }
    public string ExecutableName
    {
        get => Project.ExecutableName;
        set
        {
            _project.ExecutableName = value;
            RaisePropertyChanged(nameof(ExecutableName));
            RaisePropertyChanged(nameof(Project));

        }
    }
    public string Arguments
    {
        get => Project.Arguments;
        set
        {
            _project.Arguments = value;
            RaisePropertyChanged(nameof(Arguments));
            RaisePropertyChanged(nameof(Project));

        }
    }
    public bool IsService
    {
        get => Project.IsService;
        set
        {
            _project.IsService = value;
            RaisePropertyChanged(nameof(IsService));
            RaisePropertyChanged(nameof(Project));

        }
    }
    public ProjectType ProjectType
    {
        get => Project.ProjectType;
        set
        {
            _project.ProjectType = value;
            RaisePropertyChanged(nameof(ProjectType));
            RaisePropertyChanged(nameof(Project));

        }
    }
    #endregion

    public void Clear()
    {
        LocalDllDirRoot = string.Empty;
        RemoteDllDirRoot = string.Empty;
        ExecutableName = string.Empty;
        IsService = false;
        Arguments = string.Empty;
        ProjectType = ProjectType.None;
    }

        public ProjectDescriptor Project
        {
            get => _project;

            set
            {
                if (value == null) 
                    return;
                _project = (ProjectDescriptor)value.Clone();
                UpdateProperties();
            }
        }
        public object Clone()
        {
            return Project.Clone();
        }

        public List<string> ProjectTypes => Enum.GetNames(typeof(ProjectType)).ToList();

     }
}

Example of the broken binding

在此处输入图像描述

the marked field not loading the correct selected enum value and show a blank selection, while the other properties are shown as expected.

The problem is that 'ProjectType' property in Child VM cs file not renders on startup in UI in Parent VM xaml

Thanks ahead!

ProjectTypes is a List<string> and ProjectType is a ProjectType .

The types should match so either change the type of the source collection:

public List<ProjectType> ProjectTypes => 
    Enum.GetValues(typeof(ProjectType)).OfType<ProjectType>().ToList();

...or the type of the SelectedItem source property to string .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM