Я создал средство просмотра «как» в виде дерева с настраиваемым элементом управления, который выполняет итерации через данные ObservableCollection.Структура работает, и ветви отображаются так, как ты собираешься.
Проблема в том, что мне нравится реализовывать контекстное меню, так что само по себе это не проблема.Проблема заключается в связи с переменной, которая содержит пункты меню.
Рабочее изображение меню
Если я использую DataContext = "{Binding RelativeSource = {RelativeSource Self}}" , тогда контекстное меню работает, ноне связывание в виде дерева.
работает древовидное изображение
И без Относительного Я дерево работает, но не контекстное меню.
Я тестировал много разных подходов и искал стекпотока без какого-либо рабочего решения.
Кто-нибудь, кто имеет представление о том, что я могу сделать?
Я сделал пример проекта только счто нужно, чтобы проверить это.
http://www.lizerd.se/images/Demo_relative.rar
Проект выполнен в VS2017 с C # и WPF
Спасибо
UserControl "UserControl_Item.xaml"
<UserControl x:Class="Demo_relative.UserControl_Item"
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:Demo_relative"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<!--DataContext="{Binding RelativeSource={RelativeSource Self}}"-->
<StackPanel Orientation="Vertical" Margin="24,0,0,0" >
<StackPanel Orientation="Vertical">
<TextBox Text="{Binding TextString}"/>
<Label Content="Click here for menu" >
<Label.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Header}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Label.ContextMenu>
</Label>
</StackPanel>
<ItemsControl ItemsSource="{Binding UserControlHandlerSource.SubErrors, RelativeSource={RelativeSource AncestorType=UserControl}}" Grid.Row="2" Grid.Column="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="0,0,0,0">
<local:UserControl_Item UserControlHandlerSource="{Binding}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
UserControl "UserControl_Item.cs"
namespace Demo_relative
{
/// <summary>
/// Interaction logic for UserControl.xaml
/// </summary>
public partial class UserControl_Item : UserControl, INotifyPropertyChanged
{
// Holds Menu items
private ObservableCollection<FileMenu> _menuItems = new ObservableCollection<FileMenu>();
public ObservableCollection<FileMenu> MenuItems
{
get { return _menuItems; }
set { _menuItems = value; OnPropertyChanged("MenuItems"); }
}
public UserControl_Item()
{
InitializeComponent();
FillMenuItems();
}
// Result data for this function
public ReturnResualt UserControlHandlerSource
{
get
{
return (ReturnResualt)GetValue(UserControlHandlerSourceProperty);
}
set
{
SetValue(UserControlHandlerSourceProperty, value);
}
}
// <summary>
// Identified the Label dependency property
// </summary>
public static readonly DependencyProperty UserControlHandlerSourceProperty =
DependencyProperty.Register("UserControlHandlerSource", typeof(ReturnResualt),
typeof(UserControl_Item), new PropertyMetadata(new ReturnResualt()));
public void FillMenuItems()
{
// Create a new Menu Item
FileMenu fm = new FileMenu();
fm.Header = "Menu 1";
MenuItems.Add(fm);
// Create a new Menu Item
FileMenu fm2 = new FileMenu();
fm2.Header = "Menu 2";
MenuItems.Add(fm2);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(
this, new PropertyChangedEventArgs(propName));
}
}
#endregion
}
public class ReturnResualt : INotifyPropertyChanged
{
private string _TextString = "";
public string TextString
{
get { return _TextString; }
set { _TextString = value; OnPropertyChanged("TextString"); }
}
private ObservableCollection<ReturnResualt> _SubErrors = new ObservableCollection<ReturnResualt>();
public ObservableCollection<ReturnResualt> SubErrors
{
get { return _SubErrors; }
set { _SubErrors = value; OnPropertyChanged("SubErrors"); }
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(
this, new PropertyChangedEventArgs(propName));
}
}
#endregion
}
}
MainWindow.xaml
<Window x:Class="Demo_relative.MainWindow"
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:Demo_relative"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<local:UserControl_Item UserControlHandlerSource="{Binding ErrorHandler, Mode=TwoWay}"/>
</ScrollViewer>
</Grid>
MainWindow.cs
namespace Demo_relative
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
/// Result data for this function
private ReturnResualt _ErrorHandler = new ReturnResualt();
public ReturnResualt ErrorHandler
{
get { return _ErrorHandler; }
set { _ErrorHandler = value; OnPropertyChanged("ErrorHandler"); }
}
public MainWindow()
{
InitializeComponent();
ErrorHandler.TextString = "Main";
ReturnResualt RR = new ReturnResualt();
RR.TextString = "Sub Entry 1";
ReturnResualt RR1 = new ReturnResualt();
RR1.TextString = "Sub sub Entry 2";
ReturnResualt RR2 = new ReturnResualt();
RR2.TextString = "Sub sub sub Entry 3";
RR1.SubErrors.Add(RR2);
RR.SubErrors.Add(RR1);
ErrorHandler.SubErrors.Add(RR);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(
this, new PropertyChangedEventArgs(propName));
}
}
#endregion
}
}