C# WPF窗口隐藏内容相关属性
我想创建一个C# WPF窗口隐藏内容相关属性,c#,wpf,dependency-properties,C#,Wpf,Dependency Properties,我想创建一个窗口,重新声明它自己的DependencyProperty,名为Content 公共部分类信息窗口:窗口 { public static new readonly dependencProperty ContentProperty=dependencProperty.Register(“内容”、typeof(对象)、typeof(信息窗口)、new PropertyMetadata(null)); 公共对象内容 { 获取{返回GetValue(ContentProperty);} s
窗口
,重新声明它自己的DependencyProperty,名为Content
公共部分类信息窗口:窗口
{
public static new readonly dependencProperty ContentProperty=dependencProperty.Register(“内容”、typeof(对象)、typeof(信息窗口)、new PropertyMetadata(null));
公共对象内容
{
获取{返回GetValue(ContentProperty);}
set{SetValue(ContentProperty,value);}
}
}
和XAML绑定这个属性
它工作得很好,只是VisualStudio设计器抱怨在遍历树时超出了逻辑树深度。这可能表示树中有一个循环。
有没有办法告诉设计师绑定到
InfoWindow.Content
而不是Window.Content
?或者隐藏属性是一个坏主意,我应该重命名我的属性吗?我在这里试图实现的是动态定义用于显示不同视图以导航到不同表单的按钮的想法。(见下文:)
视图和视图模型之间的链接设置在Dictionary View_ViewModel中,按下按钮时,该视图用于标识要为当前视图设置的视图。
(注意:我尝试使用最基本的对象,避免使用IOC容器等,以便更容易理解代码)
要记住的最重要的事情是正确设置DataContext,否则在遍历树时将超出逻辑树深度。错误。您可以在视图的代码隐藏中或在XAML中执行此操作。
例如:
或
我在这里试图实现的是动态定义按钮的想法,这些按钮用于显示不同的视图以导航到不同的表单。(见下文:) 视图和视图模型之间的链接设置在Dictionary View_ViewModel中,按下按钮时,该视图用于标识要为当前视图设置的视图。 (注意:我尝试使用最基本的对象,避免使用IOC容器等,以便更容易理解代码) 要记住的最重要的事情是正确设置DataContext,否则在遍历树时将超出逻辑树深度。错误。您可以在视图的代码隐藏中或在XAML中执行此操作。 例如: 或
我认为想出一个不同的名字比试图掩盖它更好。如果没有其他原因,只是因为其他人看代码时可能会感到困惑。您的声明实际上注册了一个名为
UserContent
的属性,因此您可能绑定到了错误的对象。不管怎样,我都会叫它别的名字,否则你会感到困惑。@Charles Mager我已经修复了代码,现在它是内容
。Thx.我认为用一个不同的名字比试图掩盖它更好。如果没有其他原因,只是因为其他人看代码时可能会感到困惑。您的声明实际上注册了一个名为UserContent
的属性,因此您可能绑定到了错误的对象。不管怎样,我都会叫它别的名字,否则你会感到困惑。@Charles Mager我已经修复了代码,现在它是内容
。Thx.我认为用一个不同的名字比试图掩盖它更好。如果没有其他原因,只是因为其他人看代码时可能会感到困惑。您的声明实际上注册了一个名为UserContent
的属性,因此您可能绑定到了错误的对象。不管怎样,我都会叫它别的名字,否则你会感到困惑。@Charles Mager我已经修复了代码,现在它是内容
。这与问题中的问题不同。这与问题中的问题不同。这与问题中的问题不同。
public partial class SetupForm : UserControl
{
public SetupForm()
{
InitializeComponent();
DataContext = new SetupFormVM();
}
}
<UserControl.DataContext>
<SaleVM:SalesEntryVM />
</UserControl.DataContext>
<Window x:Class="MyNameSpace.Views.ApplicationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:local="clr-namespace:MyNameSpace.Views"
mc:Ignorable="d"
Title="ApplicationWindow" Height="Auto" Width="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition /> -------------------> repeated five times
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition /> -------------------------> repeated five times
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="5" >
<!-- Bind to List of Pages -->
<ItemsControl ItemsSource="{Binding ControlItemsNamesList}" DockPanel.Dock="Top" >
<!-- Stack the buttons horizontally --> The list contains the labels to assign to the buttons
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate> ---------------------------------------> This to stack the buttons Horizontally
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- This looks at the list items and creates a button with ControlName -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding ControlName}"
Command="{Binding DataContext.ChangeViewCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" ------> This is important for the Buttons to work Window or ContentControl.
CommandParameter="{Binding }"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
<ContentControl Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="5" Grid.RowSpan="4" Content="{Binding CurrentView}"/> ---------> This is where I want the new Windows to appear when I click the button
</Grid>
<UserControl x:Class="MyNameSpace.Views.SetupForm"
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"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition /> ------------------- repeated five times
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/> ------------------- repeated five times
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Grid.Column="0" Grid.RowSpan="5" Background="AliceBlue" Margin="0,0,0,0" >
<!-- Bind to List of Pages -->
<ItemsControl ItemsSource="{Binding ControlItemsNamesList}" DockPanel.Dock="Left" >
<!-- Stack the buttons horizontally -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- This looks at the list items and creates a button with ControlName -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding ControlName}"
Command="{Binding DataContext.ChangeViewCommand, RelativeSource={RelativeSource AncestorType={x:Type ContentControl}}}"
CommandParameter="{Binding }"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
<ContentControl Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="5" Grid.RowSpan="4" Content="{Binding CurrentView}"/>
</Grid>
</UserControl>
using Products.MVVMLibrary;
using Products.MVVMLibrary.Interfaces;
using MyNameSpace.Views;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Input;
namespace MyNameSpace.ViewModel
{
public class ApplicationVM : ObservableObject
{
private MyNameSpace IControlItem currentNavigationItem;
private MyNameSpace ContentControl currentView;
private MyNameSpace List<IControlItem> NavigationList;
private MyNameSpace ICommand changeViewCommand;
private MyNameSpace ViewConverter viewDictionary;
private MyNameSpace Dictionary<string, LinkViewToViewModel> View_ViewModel;
public ApplicationVM()
{
viewDictionary = new ViewConverter();
View_ViewModel = new Dictionary<string, LinkViewToViewModel>();
NavigationList = new List<IControlItem>();
InitialiseLists();
}
private MyNameSpace void AddControlNavigationItems(string name, ContentControl view, ObservableObject viewModel)
{
View_ViewModel.Add(name, new LinkViewToViewModel(view, viewModel));
IControlItem item = (IControlItem)viewModel;
NavigationList.Add(item);
}
private MyNameSpace void InitialiseLists()
{
AddControlNavigationItems("Sales", new SalesForm(), new SalesEntryVM());
AddControlNavigationItems("Purchases", new PurchaseEntryForm(), new PurchasesVM());
AddControlNavigationItems("Setup", new SetupForm(), new SetupFormVM());
//Use the property instead which creates the instance and triggers property change
CurrentViewModel = (IControlItem)View_ViewModel[View_ViewModel.Keys.ElementAt(0)].ViewModel;
CurrentView = View_ViewModel[View_ViewModel.Keys.ElementAt(0)].View;
}
public List<IControlItem> ControlItemsNamesList
{
get => NavigationList;
}
/// <summary>
/// Provides a list of names for Navigation controls to the control item
/// </summary>
public Dictionary<string, LinkViewToViewModel> ApplicationViews
{
get
{
return View_ViewModel;
}
set
{
View_ViewModel = value;
}
}
public ContentControl CurrentView
{
get
{
return currentView;
}
set
{
currentView = value;
OnPropertyChanged("CurrentView");
}
}
public IControlItem CurrentViewModel
{
get
{
return currentNavigationItem;
}
set
{
if (currentNavigationItem != value)
{
currentNavigationItem = value;
OnPropertyChanged("CurrentViewModel");
}
}
}
/// <summary>
/// This property is bound to Button Command in XAML.
/// Calls ChangeViewModel which sets the CurrentViewModel
/// </summary>
public ICommand ChangeViewCommand
{
get
{
if (changeViewCommand == null)
{
changeViewCommand = new ButtonClick(
p => ViewChange((IControlItem)p), CanExecute);
}
return changeViewCommand;
}
}
#region Methods
private MyNameSpace void ViewChange(IControlItem viewname)
{
foreach (KeyValuePair<string, LinkViewToViewModel> item in View_ViewModel)
{
if (item.Key == viewname.ControlName)
{//Set the properties of View and ViewModel so they fire PropertyChange event
CurrentViewModel = (IControlItem)item.Value.ViewModel;
CurrentView = item.Value.View;
break;
}
}
}
private MyNameSpace bool CanExecute()
{
return true;
}
#endregion
}
}
public class LinkViewToViewModel
{
public LinkViewToViewModel(ContentControl view, ObservableObject viewModel)
{
View = view;
ViewModel = viewModel;
}
public ContentControl View { get; set; }
public ObservableObject ViewModel { get; set; }
}