Si funcionar del todo con el TreeView
This commit is contained in:
parent
51e70b706f
commit
dc01704da6
|
@ -22,6 +22,7 @@ using ClosedXML.Excel;
|
|||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CtrEditor.PopUps;
|
||||
using CtrEditor.ObjetosSim.UserControls;
|
||||
|
||||
namespace CtrEditor
|
||||
{
|
||||
|
@ -153,11 +154,11 @@ namespace CtrEditor
|
|||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private osBase selectedItemOsList;
|
||||
private TreeItemViewModel selectedItemOsList;
|
||||
|
||||
partial void OnSelectedItemOsListChanged(osBase value)
|
||||
partial void OnSelectedItemOsListChanged(TreeItemViewModel value)
|
||||
{
|
||||
if (value != null)
|
||||
if (value.Item != null)
|
||||
habilitarEliminarUserControl = true;
|
||||
else
|
||||
habilitarEliminarUserControl = false;
|
||||
|
@ -183,6 +184,8 @@ namespace CtrEditor
|
|||
datosDeTrabajo = new DatosDeTrabajo();
|
||||
|
||||
ObjetosSimulables = new ObservableCollection<osBase>();
|
||||
TypeDecorationManager.AddExpandableIListConverter<osBase>(objetosSimulables.GetType());
|
||||
|
||||
|
||||
ListaOsBase = new ObservableCollection<TipoSimulable>();
|
||||
|
||||
|
@ -296,7 +299,7 @@ namespace CtrEditor
|
|||
|
||||
private void DuplicarUserControl()
|
||||
{
|
||||
if (SelectedItemOsList is osBase objDuplicar)
|
||||
if (SelectedItemOsList.Item is osBase objDuplicar)
|
||||
DuplicarObjeto(objDuplicar, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
|
@ -348,7 +351,7 @@ namespace CtrEditor
|
|||
|
||||
private void EliminarUserControl()
|
||||
{
|
||||
if (SelectedItemOsList is osBase objEliminar)
|
||||
if (SelectedItemOsList.Item is osBase objEliminar)
|
||||
{
|
||||
RemoverObjetoSimulable(objEliminar);
|
||||
|
||||
|
|
|
@ -197,35 +197,18 @@
|
|||
<Button Command="{Binding TBAssingPagesCommand}" ToolTip="Assing Pages">
|
||||
<StackPanel>
|
||||
<Image Source="Icons/choose.png" Width="16" Height="16" />
|
||||
<TextBlock Text="Assing Pages" />
|
||||
<TextBlock Text="Assing Pages" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
</ToolBar>
|
||||
</ToolBarTray>
|
||||
|
||||
<TreeView x:Name="TreeViewOs" Grid.Row="1" Margin="5" ItemsSource="{Binding ObjetosSimulables}"
|
||||
SelectedItemChanged="TreeViewOs_SelectedItemChanged">
|
||||
<TreeView.ItemTemplate>
|
||||
<HierarchicalDataTemplate ItemsSource="{Binding Clones}">
|
||||
<TextBlock Text="{Binding Nombre}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=Enable_On_All_Pages}" Value="True">
|
||||
<Setter Property="Foreground" Value="Blue" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=Enable_On_All_Pages}" Value="False">
|
||||
<Setter Property="Foreground" Value="Black" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</HierarchicalDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
|
||||
<uc:TreeListControlOS x:Name="ListaOS" Grid.Row="1" Margin="5" ItemsSource="{Binding DataContext.ObjetosSimulables,
|
||||
RelativeSource={RelativeSource AncestorType=Window}}"
|
||||
SelectedItem="{Binding SelectedItemOsList, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||
SelectionChanged="TreeListControl_SelectionChanged" />
|
||||
|
||||
<!-- GridSplitter -->
|
||||
<GridSplitter Grid.Row="2" Height="5" HorizontalAlignment="Stretch" Background="Gray"
|
||||
ResizeDirection="Rows" VerticalAlignment="Center" />
|
||||
|
|
|
@ -9,6 +9,8 @@ using UserControl = System.Windows.Controls.UserControl;
|
|||
using CtrEditor.ObjetosSim;
|
||||
using System.Windows.Threading;
|
||||
using System.Diagnostics;
|
||||
using CtrEditor.ObjetosSim.UserControls;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
|
||||
|
||||
namespace CtrEditor
|
||||
|
@ -144,7 +146,7 @@ namespace CtrEditor
|
|||
var viewModel = DataContext as MainViewModel;
|
||||
if (viewModel != null)
|
||||
{
|
||||
viewModel.SelectedItemOsList = datos; // Esto desencadenará ListaOs_SelectionChanged
|
||||
ListaOS.SelectedItem = ListaOS.FindViewModelForItem(datos); // Esto desencadenará ListaOs_SelectionChanged
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,15 +462,6 @@ namespace CtrEditor
|
|||
tt.Y = relativeY - cursorPosition.Y * st.ScaleY;
|
||||
}
|
||||
|
||||
private void TreeViewOs_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
//PanelEdicion.Children.Clear(); // Limpiar el panel existente
|
||||
UserControlFactory.LimpiarPropiedadesosDatos(PanelEdicion);
|
||||
|
||||
if (e.NewValue != null && e.NewValue is osBase selectedObject)
|
||||
CargarPropiedadesosDatos(selectedObject);
|
||||
}
|
||||
|
||||
private void CargarPropiedadesosDatos(osBase selectedObject)
|
||||
{
|
||||
if (DataContext is MainViewModel viewModel)
|
||||
|
@ -483,6 +476,14 @@ namespace CtrEditor
|
|||
}
|
||||
}
|
||||
|
||||
private void TreeListControl_SelectionChanged(object sender, ObjetosSim.UserControls.SelectionChangedEventArgs e)
|
||||
{
|
||||
//PanelEdicion.Children.Clear(); // Limpiar el panel existente
|
||||
UserControlFactory.LimpiarPropiedadesosDatos(PanelEdicion);
|
||||
|
||||
if (e.SelectedItem.Item != null && e.SelectedItem.Item is osBase selectedObject)
|
||||
CargarPropiedadesosDatos(selectedObject);
|
||||
}
|
||||
}
|
||||
|
||||
public class FloatValidationRule : ValidationRule
|
||||
|
|
|
@ -32,18 +32,6 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
|||
[property: Category("Tag Extraction:")]
|
||||
bool extraer;
|
||||
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Description("Autocreated and cloned with Search Templates")]
|
||||
[property: Category("Tag Extraction:")]
|
||||
bool cloned;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Description("Autocreated and cloned with Search Templates")]
|
||||
[property: Category("Tag Extraction:")]
|
||||
[property: Hidden]
|
||||
UniqueId cloned_from;
|
||||
|
||||
[ObservableProperty]
|
||||
bool new_Row;
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<UserControl x:Class="CtrEditor.ObjetosSim.UserControls.TreeListControlOS"
|
||||
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:CtrEditor.ObjetosSim.UserControls"
|
||||
mc:Ignorable="d"
|
||||
DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}">
|
||||
|
||||
<Grid>
|
||||
<TreeView x:Name="treeView" ItemsSource="{Binding Items}" SelectedItemChanged="TreeView_SelectedItemChanged"
|
||||
local:TreeViewSelectedItemExBehavior.SelectedItemEx="{Binding SelectedItemTreeViewSs}">
|
||||
<TreeView.ItemTemplate>
|
||||
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
||||
<TextBlock Text="{Binding Item.Nombre}" />
|
||||
</HierarchicalDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,365 @@
|
|||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using Xceed.Wpf.Toolkit.Primitives;
|
||||
|
||||
namespace CtrEditor.ObjetosSim.UserControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for TreeListControlOS.xaml
|
||||
/// </summary>
|
||||
public partial class TreeListControlOS : UserControl
|
||||
{
|
||||
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
|
||||
nameof(ItemsSource), typeof(ObservableCollection<osBase>), typeof(TreeListControlOS), new PropertyMetadata(null, OnItemsSourceChanged));
|
||||
|
||||
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
|
||||
nameof(SelectedItem), typeof(TreeItemViewModel), typeof(TreeListControlOS), new PropertyMetadata(null, OnSelectedItemChanged));
|
||||
|
||||
|
||||
public event EventHandler<SelectionChangedEventArgs> SelectionChanged;
|
||||
|
||||
public ObservableCollection<osBase> ItemsSource
|
||||
{
|
||||
get => (ObservableCollection<osBase>)GetValue(ItemsSourceProperty);
|
||||
set => SetValue(ItemsSourceProperty, value);
|
||||
}
|
||||
|
||||
public TreeItemViewModel SelectedItem
|
||||
{
|
||||
get => (TreeItemViewModel)GetValue(SelectedItemProperty);
|
||||
set => SetValue(SelectedItemProperty, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<TreeItemViewModel> Items { get; set; } = new ObservableCollection<TreeItemViewModel>();
|
||||
|
||||
public TreeListControlOS()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is TreeListControlOS control)
|
||||
{
|
||||
control.LoadItems((ObservableCollection<osBase>)e.NewValue);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is TreeListControlOS control && e.NewValue is TreeItemViewModel newItem)
|
||||
{
|
||||
// Update the TreeView selection if necessary
|
||||
control.UpdateTreeViewSelection(newItem);
|
||||
control.OnSelectionChanged(new SelectionChangedEventArgs(newItem));
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTreeViewSelection(TreeItemViewModel selectedItem)
|
||||
{
|
||||
if (treeView != null && selectedItem != null)
|
||||
{
|
||||
TreeViewSelectedItemExBehavior.SetSelectedItemEx(treeView, selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public TreeItemViewModel FindViewModelForItem(osBase item)
|
||||
{
|
||||
foreach (var i in Items)
|
||||
{
|
||||
if (i.Item == item)
|
||||
return i;
|
||||
foreach (var child in i.Children)
|
||||
if (child.Item == item)
|
||||
return child;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
if (e.NewValue is TreeItemViewModel selectedItem)
|
||||
{
|
||||
SelectedItem = selectedItem;
|
||||
OnSelectionChanged(new SelectionChangedEventArgs(selectedItem));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChanged(SelectionChangedEventArgs e)
|
||||
{
|
||||
SelectionChanged?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void LoadItems(ObservableCollection<osBase> allItems)
|
||||
{
|
||||
Items.Clear();
|
||||
if (allItems == null) return;
|
||||
|
||||
var rootItems = allItems.Where(i => !i.Cloned);
|
||||
foreach (var item in rootItems)
|
||||
{
|
||||
Items.Add(new TreeItemViewModel(item, allItems));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public partial class vmTreeListControlOS : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
private object selectedItemTreeViewSs = new object();
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<object> selectedItemsTreeViewSs = new ObservableCollection<object>();
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<TreeItemViewModel> itemsTreeViewSs = new ObservableCollection<TreeItemViewModel>();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class TreeItemViewModel
|
||||
{
|
||||
public osBase Item { get; set; }
|
||||
public ObservableCollection<TreeItemViewModel> Children { get; set; } = new ObservableCollection<TreeItemViewModel>();
|
||||
|
||||
public TreeItemViewModel(osBase item, ObservableCollection<osBase> allItems)
|
||||
{
|
||||
Item = item;
|
||||
LoadChildren(allItems);
|
||||
}
|
||||
|
||||
private void LoadChildren(ObservableCollection<osBase> allItems)
|
||||
{
|
||||
foreach (var child in allItems.Where(i => i.Cloned && i.Cloned_from == Item.Id))
|
||||
{
|
||||
Children.Add(new TreeItemViewModel(child, allItems));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cambia la clase SelectionChangedEventArgs
|
||||
public class SelectionChangedEventArgs : EventArgs
|
||||
{
|
||||
public TreeItemViewModel SelectedItem { get; }
|
||||
|
||||
public SelectionChangedEventArgs(TreeItemViewModel selectedItem)
|
||||
{
|
||||
SelectedItem = selectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TreeViewSelectedItemExBehavior
|
||||
{
|
||||
private static List<TreeView> isRegisteredToSelectionChanged = new List<TreeView>();
|
||||
|
||||
public static readonly DependencyProperty SelectedItemExProperty =
|
||||
DependencyProperty.RegisterAttached("SelectedItemEx",
|
||||
typeof(object),
|
||||
typeof(TreeViewSelectedItemExBehavior),
|
||||
new FrameworkPropertyMetadata(new object(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedItemExChanged, null));
|
||||
|
||||
#region SelectedItemEx
|
||||
|
||||
public static object GetSelectedItemEx(TreeView target)
|
||||
{
|
||||
return target.GetValue(SelectedItemExProperty);
|
||||
}
|
||||
|
||||
public static void SetSelectedItemEx(TreeView target, object value)
|
||||
{
|
||||
target.SetValue(SelectedItemExProperty, value);
|
||||
var treeViewItemToSelect = GetTreeViewItem(target, value);
|
||||
if (treeViewItemToSelect == null)
|
||||
{
|
||||
if (target.SelectedItem == null)
|
||||
return;
|
||||
var treeViewItemToUnSelect = GetTreeViewItem(target, target.SelectedItem);
|
||||
treeViewItemToUnSelect.IsSelected = false;
|
||||
}
|
||||
else
|
||||
treeViewItemToSelect.IsSelected = true;
|
||||
}
|
||||
|
||||
public static void OnSelectedItemExChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var treeView = depObj as TreeView;
|
||||
if (treeView == null)
|
||||
return;
|
||||
if (!isRegisteredToSelectionChanged.Contains(treeView))
|
||||
{
|
||||
treeView.SelectedItemChanged += TreeView_SelectedItemChanged;
|
||||
isRegisteredToSelectionChanged.Add(treeView);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
var treeView = (TreeView)sender;
|
||||
SetSelectedItemEx(treeView, e.NewValue);
|
||||
}
|
||||
|
||||
#region Helper Structures & Methods
|
||||
|
||||
public class MyVirtualizingStackPanel : VirtualizingStackPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Publically expose BringIndexIntoView.
|
||||
/// </summary>
|
||||
public void BringIntoView(int index)
|
||||
{
|
||||
BringIndexIntoView(index);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Recursively search for an item in this subtree.</summary>
|
||||
/// <param name="container">The parent ItemsControl. This can be a TreeView or a TreeViewItem.</param>
|
||||
/// <param name="item">The item to search for.</param>
|
||||
/// <returns>The TreeViewItem that contains the specified item.</returns>
|
||||
private static TreeViewItem GetTreeViewItem(ItemsControl container, object item)
|
||||
{
|
||||
if (container != null)
|
||||
{
|
||||
if (container.DataContext == item)
|
||||
{
|
||||
return container as TreeViewItem;
|
||||
}
|
||||
|
||||
// Expand the current container
|
||||
if (container is TreeViewItem && !((TreeViewItem)container).IsExpanded)
|
||||
{
|
||||
container.SetValue(TreeViewItem.IsExpandedProperty, true);
|
||||
}
|
||||
|
||||
// Try to generate the ItemsPresenter and the ItemsPanel.
|
||||
// by calling ApplyTemplate. Note that in the
|
||||
// virtualizing case even if the item is marked
|
||||
// expanded we still need to do this step in order to
|
||||
// regenerate the visuals because they may have been virtualized away.
|
||||
|
||||
container.ApplyTemplate();
|
||||
ItemsPresenter itemsPresenter =
|
||||
(ItemsPresenter)container.Template.FindName("ItemsHost", container);
|
||||
if (itemsPresenter != null)
|
||||
{
|
||||
itemsPresenter.ApplyTemplate();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The Tree template has not named the ItemsPresenter,
|
||||
// so walk the descendents and find the child.
|
||||
itemsPresenter = FindVisualChild<ItemsPresenter>(container);
|
||||
if (itemsPresenter == null)
|
||||
{
|
||||
container.UpdateLayout();
|
||||
|
||||
itemsPresenter = FindVisualChild<ItemsPresenter>(container);
|
||||
}
|
||||
}
|
||||
|
||||
Panel itemsHostPanel = (Panel)VisualTreeHelper.GetChild(itemsPresenter, 0);
|
||||
|
||||
|
||||
// Ensure that the generator for this panel has been created.
|
||||
UIElementCollection children = itemsHostPanel.Children;
|
||||
|
||||
MyVirtualizingStackPanel virtualizingPanel =
|
||||
itemsHostPanel as MyVirtualizingStackPanel;
|
||||
|
||||
for (int i = 0, count = container.Items.Count; i < count; i++)
|
||||
{
|
||||
TreeViewItem subContainer;
|
||||
if (virtualizingPanel != null)
|
||||
{
|
||||
// Bring the item into view so
|
||||
// that the container will be generated.
|
||||
virtualizingPanel.BringIntoView(i);
|
||||
|
||||
subContainer =
|
||||
(TreeViewItem)container.ItemContainerGenerator.
|
||||
ContainerFromIndex(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
subContainer =
|
||||
(TreeViewItem)container.ItemContainerGenerator.
|
||||
ContainerFromIndex(i);
|
||||
|
||||
// Bring the item into view to maintain the
|
||||
// same behavior as with a virtualizing panel.
|
||||
subContainer.BringIntoView();
|
||||
}
|
||||
|
||||
if (subContainer != null)
|
||||
{
|
||||
// Search the next level for the object.
|
||||
TreeViewItem resultContainer = GetTreeViewItem(subContainer, item);
|
||||
if (resultContainer != null)
|
||||
{
|
||||
return resultContainer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The object is not under this TreeViewItem
|
||||
// so collapse it.
|
||||
subContainer.IsExpanded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Search for an element of a certain type in the visual tree.</summary>
|
||||
/// <typeparam name="T">The type of element to find.</typeparam>
|
||||
/// <param name="visual">The parent element.</param>
|
||||
/// <returns></returns>
|
||||
private static T FindVisualChild<T>(Visual visual) where T : Visual
|
||||
{
|
||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
|
||||
{
|
||||
Visual child = (Visual)VisualTreeHelper.GetChild(visual, i);
|
||||
if (child != null)
|
||||
{
|
||||
T correctlyTyped = child as T;
|
||||
if (correctlyTyped != null)
|
||||
{
|
||||
return correctlyTyped;
|
||||
}
|
||||
|
||||
T descendent = FindVisualChild<T>(child);
|
||||
if (descendent != null)
|
||||
{
|
||||
return descendent;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
|
@ -320,6 +320,17 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Description("Autocreated and cloned with Search Templates")]
|
||||
[property: Category("Tag Extraction:")]
|
||||
bool cloned;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Description("Autocreated and cloned with Search Templates")]
|
||||
[property: Category("Tag Extraction:")]
|
||||
[property: Hidden]
|
||||
UniqueId cloned_from;
|
||||
|
||||
|
||||
private async void TimerCallback(object state)
|
||||
{
|
||||
|
|
117
XAMLhelpers.cs
117
XAMLhelpers.cs
|
@ -10,9 +10,126 @@ using Xceed.Wpf.Toolkit.PropertyGrid;
|
|||
using CtrEditor.ObjetosSim.Extraccion_Datos;
|
||||
using CtrEditor.ObjetosSim;
|
||||
using System.Collections.ObjectModel;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
using System.Collections;
|
||||
|
||||
namespace CtrEditor
|
||||
{
|
||||
public class ListItemPropertyDescriptor<T> : PropertyDescriptor
|
||||
{
|
||||
private readonly IList<T> owner;
|
||||
private readonly int index;
|
||||
|
||||
public ListItemPropertyDescriptor(IList<T> owner, int index) : base($"[{index}]", null)
|
||||
{
|
||||
this.owner = owner;
|
||||
this.index = index;
|
||||
|
||||
}
|
||||
|
||||
public override AttributeCollection Attributes
|
||||
{
|
||||
get
|
||||
{
|
||||
var attributes = TypeDescriptor.GetAttributes(GetValue(null), false);
|
||||
//If the Xceed expandable object attribute is not applied then apply it
|
||||
if (!attributes.OfType<ExpandableObjectAttribute>().Any())
|
||||
{
|
||||
attributes = AddAttribute(new ExpandableObjectAttribute(), attributes);
|
||||
}
|
||||
|
||||
//set the xceed order attribute
|
||||
attributes = AddAttribute(new PropertyOrderAttribute(index), attributes);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes)
|
||||
{
|
||||
Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1];
|
||||
oldAttributes.CopyTo(newAttributes, 1);
|
||||
newAttributes[0] = newAttribute;
|
||||
|
||||
return new AttributeCollection(newAttributes);
|
||||
}
|
||||
|
||||
public override bool CanResetValue(object component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override object GetValue(object component)
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
|
||||
private T Value
|
||||
=> owner[index];
|
||||
|
||||
public override void ResetValue(object component)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetValue(object component, object value)
|
||||
{
|
||||
owner[index] = (T)value;
|
||||
}
|
||||
|
||||
public override bool ShouldSerializeValue(object component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override Type ComponentType
|
||||
=> owner.GetType();
|
||||
|
||||
public override bool IsReadOnly
|
||||
=> false;
|
||||
|
||||
public override Type PropertyType
|
||||
=> Value?.GetType();
|
||||
|
||||
}
|
||||
public class MyExpandableIListConverter<T> : ExpandableObjectConverter
|
||||
{
|
||||
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
|
||||
{
|
||||
if (value is IList<T> list)
|
||||
{
|
||||
PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null);
|
||||
IEnumerator enumerator = list.GetEnumerator();
|
||||
int counter = -1;
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
counter++;
|
||||
propDescriptions.Add(new ListItemPropertyDescriptor<T>(list, counter));
|
||||
|
||||
}
|
||||
return propDescriptions;
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.GetProperties(context, value, attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeDecorationManager
|
||||
{
|
||||
public static void AddExpandableObjectConverter(Type T)
|
||||
{
|
||||
TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(ExpandableObjectConverter)));
|
||||
TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute());
|
||||
}
|
||||
|
||||
public static void AddExpandableIListConverter<I>(Type T)
|
||||
{
|
||||
TypeDescriptor.AddAttributes(T, new TypeConverterAttribute(typeof(MyExpandableIListConverter<I>)));
|
||||
TypeDescriptor.AddAttributes(T, new ExpandableObjectAttribute());
|
||||
}
|
||||
}
|
||||
|
||||
public class SubclassFilterConverter : IValueConverter
|
||||
{
|
||||
public Type TargetType { get; set; }
|
||||
|
|
Loading…
Reference in New Issue