简体   繁体   English

绑定到子视图中的枚举 model combobox object 不在 UI 上呈现

[英]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,我有一个父 ViewModel,其中包含一个子视图 model object 里面有一些枚举,

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.当我打开 UI 时,我看到枚举值在第一次加载时未按预期从 RaisePropertyChanged 事件呈现,但是,在从 UI 设置值后,该值会按预期更改并呈现。

Parent VM xaml父虚拟机 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父虚拟机 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子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子 VM cs 文件

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问题是子 VM cs 文件中的“ProjectType”属性在父 VM xaml 的 UI 中启动时不呈现

Thanks ahead!提前谢谢!

ProjectTypes is a List<string> and ProjectType is a ProjectType . ProjectTypesList<string>并且ProjectTypeProjectType

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 . ...或SelectedItem源属性的类型为string

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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