Public 变量未显示在 class 成员列表中
Public variable doesn't show up in class members list
我对这门语言完全陌生,所以我觉得这个问题有点傻..
我正在尝试通过 his example repository 中的示例使用 MahApps.Metro 框架创建一个汉堡菜单,V4 版本带有 MVVM。
复制他的例子的所有结构,它工作正常,但现在我不知道如何继续。我不知道如何从我的 SearchViewModel 获取我的 MainViewModel 的属性,因为在访问对象时我看不到它的属性。
此外,我不知道如何绑定这些属性或如何通过使用 MainViewModel 属性的操作 link SearchView.xaml 中的按钮。
这些都是与我相关的 类,但您可以按照 his example repo
中的示例
MainWindow.xaml
<Window.DataContext>
<viewModels:MainViewModel />
</Window.DataContext>
<Grid.Resources>
<core:SelectedItemToContentConverter x:Key="SelectedItemToContentConverter" />
<!-- this is the template for the items (options too) -->
<DataTemplate x:Key="MenuItemTemplate" DataType="{x:Type Controls:HamburgerMenuIconItem}">
<Grid x:Name="RootGrid" Height="48" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ContentControl Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding Icon}" Focusable="False" />
<TextBlock Grid.Column="1" VerticalAlignment="Center" FontSize="16" Text="{Binding Label}" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:HamburgerMenu}}, Path=IsPaneOpen}" Value="False">
<Setter TargetName="RootGrid" Property="ToolTip" Value="{Binding ToolTip, Mode=OneWay}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<!-- these are the templates for the view models -->
<DataTemplate DataType="{x:Type viewModels:HomeViewModel}">
<views:HomeView DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:PrivateViewModel}">
<views:PrivateView DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:SettingsViewModel}">
<views:SettingsView DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:AboutViewModel}">
<views:AboutView DataContext="{Binding}" />
</DataTemplate>
<Controls:HamburgerMenu Grid.Row="1" x:Name="HamburgerMenuControl" HamburgerVisibility="Hidden" HamburgerWidth="48" ItemTemplate="{StaticResource MenuItemTemplate}" ItemsSource="{Binding MenuItems}" IsPaneOpen="True" SelectedIndex="0" Style="{StaticResource HamburgerMenuCreatorsStyle}" OpenPaneLength="350" VerticalScrollBarOnLeftSide="False" Grid.RowSpan="3" Grid.ColumnSpan="2">
<!-- select the tag (ViewModel) of the selected item (options item) -->
<Controls:HamburgerMenu.Content>
<MultiBinding Converter="{StaticResource SelectedItemToContentConverter}">
<Binding FallbackValue="{x:Null}" Mode="OneWay" Path="SelectedItem.Tag" RelativeSource="{RelativeSource Self}" />
<Binding FallbackValue="{x:Null}" Mode="OneWay" Path="SelectedOptionsItem.Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Controls:HamburgerMenu.Content>
</Controls:HamburgerMenu>
</Grid.Resources>
PropertyChangedViewModel 基础模型
using System.ComponentModel;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
namespace ExampleProject.ViewModels
{
public class PropertyChangedViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
MainViewModel
namespace ExampleProject.ViewModels
{
public class MainViewModel : PropertyChangedViewModel
{
private HamburgerMenuItemCollection _menuItems;
private HamburgerMenuItemCollection _menuOptionItems;
public MainViewModel()
{
this.CreateMenuItems();
}
public void CreateMenuItems()
{
MenuItems = new HamburgerMenuItemCollection
{
new HamburgerMenuIconItem()
{
Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.Magnify},
Label = "Search Item",
ToolTip = "The Search view.",
Tag = new SearchViewModel(this)
},
new HamburgerMenuIconItem()
{
Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.CreditCardOutline},
Label = "Payment item",
ToolTip = "Payment.",
Tag = new PaymentViewModel(this)
},
new HamburgerMenuIconItem()
{
Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.BookmarkMultipleOutline},
Label = "The Bookmarks",
ToolTip = "The bookmarks item.",
Tag = new BookmarksViewModel(this)
}
};
MenuOptionItems = new HamburgerMenuItemCollection
{
new HamburgerMenuIconItem()
{
Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.Help},
Label = "About",
ToolTip = "Some help.",
Tag = new AboutViewModel(this)
}
};
}
public HamburgerMenuItemCollection MenuItems
{
get { return _menuItems; }
set
{
if (Equals(value, _menuItems)) return;
_menuItems = value;
OnPropertyChanged();
}
}
public HamburgerMenuItemCollection MenuOptionItems
{
get { return _menuOptionItems; }
set
{
if (Equals(value, _menuOptionItems)) return;
_menuOptionItems = value;
OnPropertyChanged();
}
}
}
}
SearchViewModel
namespace ExampleProject.ViewModels
{
public class SearchViewModel : PropertyChangedViewModel
{
private readonly PropertyChangedViewModel _mainViewModel;
public SearchViewModel(PropertyChangedViewModel mainViewModel)
{
_mainViewModel = mainViewModel;
}
}
}
SearchView.xaml
<UserControl x:Class="ExampleProject.Views.SearchView"
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:local="clr-namespace:ExampleProject.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock Text="Search View"
FontSize="32"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</UserControl>
SearchView.xaml(后面的代码)
namespace ExampleProject.Views
{
/// <summary>
/// Logic of interaction for SearchtView.xaml
/// </summary>
public partial class SearchView : UserControl
{
public SearchView()
{
InitializeComponent();
}
}
}
谢谢。
PropertyChangedViewModel
没有myGlobalVar
,MainViewModel
有。
您必须将 mainViewModel
转换为 MainViewModel
,因为 mainViewModel
属于 PropertyChangedViewModel
而不是 MainViewModel
.
((MainViewModel)mainViewModel).myGlobalVar = ...
这就是为什么尊重 "naming conventions" 很重要,要不是你把它命名错了 class,你就不会把它和另一个 class 搞混了。
另外,为了使绑定生效,class 成员必须是 public 属性,否则无法从 XAML 访问它,并且它不会'不会出现在 XAML 智能感知中。
如果您不希望它成为 public,您必须使用 DependencyProperty
。
我对这门语言完全陌生,所以我觉得这个问题有点傻..
我正在尝试通过 his example repository 中的示例使用 MahApps.Metro 框架创建一个汉堡菜单,V4 版本带有 MVVM。
复制他的例子的所有结构,它工作正常,但现在我不知道如何继续。我不知道如何从我的 SearchViewModel 获取我的 MainViewModel 的属性,因为在访问对象时我看不到它的属性。
此外,我不知道如何绑定这些属性或如何通过使用 MainViewModel 属性的操作 link SearchView.xaml 中的按钮。
这些都是与我相关的 类,但您可以按照 his example repo
中的示例MainWindow.xaml
<Window.DataContext>
<viewModels:MainViewModel />
</Window.DataContext>
<Grid.Resources>
<core:SelectedItemToContentConverter x:Key="SelectedItemToContentConverter" />
<!-- this is the template for the items (options too) -->
<DataTemplate x:Key="MenuItemTemplate" DataType="{x:Type Controls:HamburgerMenuIconItem}">
<Grid x:Name="RootGrid" Height="48" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ContentControl Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding Icon}" Focusable="False" />
<TextBlock Grid.Column="1" VerticalAlignment="Center" FontSize="16" Text="{Binding Label}" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:HamburgerMenu}}, Path=IsPaneOpen}" Value="False">
<Setter TargetName="RootGrid" Property="ToolTip" Value="{Binding ToolTip, Mode=OneWay}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<!-- these are the templates for the view models -->
<DataTemplate DataType="{x:Type viewModels:HomeViewModel}">
<views:HomeView DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:PrivateViewModel}">
<views:PrivateView DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:SettingsViewModel}">
<views:SettingsView DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:AboutViewModel}">
<views:AboutView DataContext="{Binding}" />
</DataTemplate>
<Controls:HamburgerMenu Grid.Row="1" x:Name="HamburgerMenuControl" HamburgerVisibility="Hidden" HamburgerWidth="48" ItemTemplate="{StaticResource MenuItemTemplate}" ItemsSource="{Binding MenuItems}" IsPaneOpen="True" SelectedIndex="0" Style="{StaticResource HamburgerMenuCreatorsStyle}" OpenPaneLength="350" VerticalScrollBarOnLeftSide="False" Grid.RowSpan="3" Grid.ColumnSpan="2">
<!-- select the tag (ViewModel) of the selected item (options item) -->
<Controls:HamburgerMenu.Content>
<MultiBinding Converter="{StaticResource SelectedItemToContentConverter}">
<Binding FallbackValue="{x:Null}" Mode="OneWay" Path="SelectedItem.Tag" RelativeSource="{RelativeSource Self}" />
<Binding FallbackValue="{x:Null}" Mode="OneWay" Path="SelectedOptionsItem.Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Controls:HamburgerMenu.Content>
</Controls:HamburgerMenu>
</Grid.Resources>
PropertyChangedViewModel 基础模型
using System.ComponentModel;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
namespace ExampleProject.ViewModels
{
public class PropertyChangedViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
MainViewModel
namespace ExampleProject.ViewModels
{
public class MainViewModel : PropertyChangedViewModel
{
private HamburgerMenuItemCollection _menuItems;
private HamburgerMenuItemCollection _menuOptionItems;
public MainViewModel()
{
this.CreateMenuItems();
}
public void CreateMenuItems()
{
MenuItems = new HamburgerMenuItemCollection
{
new HamburgerMenuIconItem()
{
Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.Magnify},
Label = "Search Item",
ToolTip = "The Search view.",
Tag = new SearchViewModel(this)
},
new HamburgerMenuIconItem()
{
Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.CreditCardOutline},
Label = "Payment item",
ToolTip = "Payment.",
Tag = new PaymentViewModel(this)
},
new HamburgerMenuIconItem()
{
Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.BookmarkMultipleOutline},
Label = "The Bookmarks",
ToolTip = "The bookmarks item.",
Tag = new BookmarksViewModel(this)
}
};
MenuOptionItems = new HamburgerMenuItemCollection
{
new HamburgerMenuIconItem()
{
Icon = new PackIconMaterial() {Kind = PackIconMaterialKind.Help},
Label = "About",
ToolTip = "Some help.",
Tag = new AboutViewModel(this)
}
};
}
public HamburgerMenuItemCollection MenuItems
{
get { return _menuItems; }
set
{
if (Equals(value, _menuItems)) return;
_menuItems = value;
OnPropertyChanged();
}
}
public HamburgerMenuItemCollection MenuOptionItems
{
get { return _menuOptionItems; }
set
{
if (Equals(value, _menuOptionItems)) return;
_menuOptionItems = value;
OnPropertyChanged();
}
}
}
}
SearchViewModel
namespace ExampleProject.ViewModels
{
public class SearchViewModel : PropertyChangedViewModel
{
private readonly PropertyChangedViewModel _mainViewModel;
public SearchViewModel(PropertyChangedViewModel mainViewModel)
{
_mainViewModel = mainViewModel;
}
}
}
SearchView.xaml
<UserControl x:Class="ExampleProject.Views.SearchView"
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:local="clr-namespace:ExampleProject.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock Text="Search View"
FontSize="32"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</UserControl>
SearchView.xaml(后面的代码)
namespace ExampleProject.Views
{
/// <summary>
/// Logic of interaction for SearchtView.xaml
/// </summary>
public partial class SearchView : UserControl
{
public SearchView()
{
InitializeComponent();
}
}
}
谢谢。
PropertyChangedViewModel
没有myGlobalVar
,MainViewModel
有。
您必须将 mainViewModel
转换为 MainViewModel
,因为 mainViewModel
属于 PropertyChangedViewModel
而不是 MainViewModel
.
((MainViewModel)mainViewModel).myGlobalVar = ...
这就是为什么尊重 "naming conventions" 很重要,要不是你把它命名错了 class,你就不会把它和另一个 class 搞混了。
另外,为了使绑定生效,class 成员必须是 public 属性,否则无法从 XAML 访问它,并且它不会'不会出现在 XAML 智能感知中。
如果您不希望它成为 public,您必须使用 DependencyProperty
。