Skale
asked on
Cannot resolve property path issue in WPF C#
Hello,
I've a menu in my MainWindow and both of them have seperate ViewModels MainWindowViewModel and MainMenuItemViewModel. It works without problem but in designer it underlined with blue color and it says "Cannot Resolve Property"
And my code is like below;
Anyone know how can i fix it? Any help would be great.
I've a menu in my MainWindow and both of them have seperate ViewModels MainWindowViewModel and MainMenuItemViewModel. It works without problem but in designer it underlined with blue color and it says "Cannot Resolve Property"
And my code is like below;
<Menu IsMainMenu="True" ItemsSource="{Binding MainMenuItemViewModel.MainMenuItems}" Grid.Column="0">
<Menu.Resources>
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
<Setter Property="Header" Value="{Binding Path=DisplayName}"/>
<Setter Property="Command" Value="{Binding Path=MainMenuItemCommand}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSeparator}" Value="true">
<Setter Property="MenuItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator Style="{DynamicResource {x:Static MenuItem.SeparatorStyleKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<HierarchicalDataTemplate
DataType="{x:Type mainMenuModel:MainMenuItem}"
ItemsSource="{Binding MainMenuItems}">
</HierarchicalDataTemplate>
</Menu.Resources>
</Menu>
Anyone know how can i fix it? Any help would be great.
ASKER
It's working without problem but it makes me sick when it shows blue underlines.
This is my MainMenuItem model:
using System.Collections.ObjectModel;
using System.Windows.Input;
using MyTool.Core;
namespace MyTool.Models.MainMenu
{
public class MainMenuItem : BindableBase
{
private string displayName;
public string DisplayName
{
get => displayName;
set => SetProperty(ref displayName, value);
}
private ICommand mainMenuItemCommand;
public ICommand MainMenuItemCommand {
get => mainMenuItemCommand;
set => SetProperty(ref mainMenuItemCommand, value);
}
private bool isSeparator;
public bool IsSeparator
{
get => isSeparator;
set => SetProperty(ref isSeparator, value);
}
public ObservableCollection<MainMenuItem> MainMenuItems { get; set; }
}
}
And this is my MainMenuItemViewModel:
using System.Collections.ObjectModel;
using System.Windows;
using MyTool.Core;
using MyTool.Models;
using MyTool.Models.MainMenu;
using MyTool.Pre;
using MyTool.Services;
using MyTool.Views.Setting;
namespace MyTool.ViewModels.MainMenu
{
public class MainMenuItemViewModel : BindableBase
{
private readonly MainWindow mainWindow;
public ObservableCollection<MainMenuItem> MainMenuItems { get; private set; }
public MainMenuItemViewModel(MainWindow mainWindow)
{
// Receive main window instance to update values on main window through this viewmodel like in OpenFileDialogCommandHandler
this.mainWindow = mainWindow;
// Add main menu items here.
MainMenuItems = new ObservableCollection<MainMenuItem>
{
new MainMenuItem
{
DisplayName="File",
MainMenuItems = new ObservableCollection<MainMenuItem>
{
new MainMenuItem { DisplayName = "Open", MainMenuItemCommand= new RelayCommand(OpenFileDialogCommandHandler)},
new MainMenuItem { DisplayName = "Reload" },
new MainMenuItem { DisplayName = "Close" },
new MainMenuItem { IsSeparator = true },
new MainMenuItem { DisplayName = "Save" },
new MainMenuItem { DisplayName = "Save As" },
new MainMenuItem { IsSeparator = true },
new MainMenuItem
{
DisplayName="Recent Models",
MainMenuItems=new ObservableCollection<MainMenuItem>
{
new MainMenuItem {DisplayName=@"C:/File1"}
}
},
new MainMenuItem {IsSeparator=true},
new MainMenuItem {DisplayName="Exit"}
}
},
new MainMenuItem
{
DisplayName="Extras",
MainMenuItems = new ObservableCollection<MainMenuItem>
{
new MainMenuItem { DisplayName = "Options", MainMenuItemCommand= new RelayCommand(OptionsCommandHandler)},
new MainMenuItem {DisplayName="Log File (Serilog)"},
new MainMenuItem {DisplayName="Log File (Com)"}
}
},
new MainMenuItem
{
DisplayName="Help",
MainMenuItems = new ObservableCollection<MainMenuItem>
{
new MainMenuItem {DisplayName="Documentation"}
}
}
};
}
/// Open File dialog from main menu will be handled through this handler
private void OpenFileDialogCommandHandler()
{
if (ScrSpck.OpenModel())
{
mainWindow.FileName = ScrSpck.CurrentModel.name;
mainWindow.FileInfoVisibility = Visibility.Visible;
}
}
/// Options from main menu will be handled through this handler
/// Window Service is used to show user control in a new window instead of main window.
private void OptionsCommandHandler()
{
WindowService windowService = new WindowService();
windowService.ShowOptionWindow(new OptionsView());
}
}
}
And this is my MainWindowViewModel
using System;
using System.Windows;
using System.Windows.Input;
using MyTool.Core;
using MyTool.Models;
using MyTool.ViewModels.MainMenu;
using MyTool.ViewModels.SideMenu;
using Serilog;
namespace MyTool.ViewModels
{
public class MainWindowViewModel : BindableBase
{
public string Title { get; set; } = "MyTool v1.0";
public ICommand ToggleButtonCommand { get; private set; }
public ICommand HelloWordCommand { get; private set; }
public ICommand GoodbyeCommand { get; private set; }
public MainMenuItemViewModel MainMenuItemViewModel { get; set; }
public MainNavigationViewModel MainNavigationViewModel { get; set; }
public MainWindow MainWindow { get; }
/// <summary>
/// This property is binded to show selected side menu item view model.
/// </summary>
private BindableBase currentViewModel;
public BindableBase CurrentViewModel
{
get => currentViewModel;
set => SetProperty(ref currentViewModel, value);
}
public MainWindowViewModel()
{
MainWindow = new MainWindow();
this.ToggleButtonCommand = new RelayCommand(IsChecked);
this.HelloWordCommand = new RelayCommand(IsClick);
this.GoodbyeCommand = new RelayCommand(IsClicked);
this.MainMenuItemViewModel = new MainMenuItemViewModel(MainWindow);
this.MainNavigationViewModel = new MainNavigationViewModel(this);
#region Logger
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(path: $"logs\\log-{Environment.UserName}-.log", rollingInterval: RollingInterval.Day, shared: true)
.CreateLogger();
#endregion
}
// Goodbye Button Click
private void IsClicked()
{
MessageBox.Show("Goodbye Button Clicked");
}
// Hello World Button Click
private void IsClick()
{
MessageBox.Show("Hello Word Button Clicked");
}
// Check is Toggle Button is Checked or not.
private void IsChecked()
{
MessageBox.Show(this.MainWindow.MenuToggleButton ? "Toggle Button Checked" : "Toggle Button UnChecked");
}
}
}
What happens if you change your style's target type from "MenuItem" to "MainMenuItem" ?
ASKER
Hi gr8gonzo,
MenuItem is MenuItem it's element for UI control :/
Did you do any of the restarting suggestions?
No response to my questions
ASKER
Yes i tried.
Is it possible to share a ZIP of your project? I'm unable to reproduce the problem with the code you provided...
This question needs an answer!
Become an EE member today
7 DAY FREE TRIALMembers can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
So if you are certain that the property does exist (you didn't share your viewmodel definition so there's no way to tell what kind of class MenuItem is), then...
First just try a simple rebuild of your solution.
If that doesn't work, close all your tabs inside VS, clean your solution, completely restart visual studio, build, and then open up the designer again.
If it still shows the same error, then maybe you're binding to the wrong class type. You can try specifying the full type name to avoid accidental ambiguity.