WPF
У меня есть TreeView (см. Ниже), для которого я создал Редактор редактирования.
Все работает правильно. Тем не менее, я хотел бы отключить TreeView во время редактирования. Когда TreeView отключен - как и элемент, украшенный для редактирования - рекламщик также отключается.
Как можно отключить TreeView (IsEnabled = false), но все же разрешить Adorner быть включенным для редактирования?
ТИА
namespace Doctor_Desk.Views.Adorners
{
public class EditSelectedItemAdorner : Adorner
{
private VisualCollection _Visuals;
private UIElement _UIElement;
private bool _IsCancel = false;
private TextBox _Textbox;
protected override int VisualChildrenCount
{
get
{
return _Visuals.Count;
}
}
// Be sure to call the base class constructor.
public EditSelectedItemAdorner(UIElement adornedElement, IConsultantTreeItem selectedItem)
: base(adornedElement)
{
_UIElement = adornedElement;
adornedElement.Visibility = Visibility.Hidden;
_Textbox = new TextBox
{
Background = Brushes.Pink,
Text = selectedItem.GetText()
};
// The VisualCollection will hold the content of this Adorner.
_Visuals = new VisualCollection(this)
{
// The _Textbox is a logical child of the VisualCollection of the Adorner. The ArrangeOverride and MeasureOverride
// will set up the Grid control for correct rendering.
_Textbox // Adding a single control for display.
};
}
/// The adorner placement is always relative to the top left corner of the adorned element. The children of the adorner are located by
/// implementing ArrangeOverride. The only other way to position the Adorner content is to use the AdornerPanel Class
/// with it's AdornerPlacementCollection Methods.
///
/// Overriding the default ArrangeOverride and MeasureOverride allows a control to be placed and diplayed in the VisualCollection.
protected override Size ArrangeOverride(Size finalSize)
{
//TextBox child = _Visuals[0] as TextBox;
//FrameworkElement element = _UIElement as FrameworkElement;
//if (element != null)
//{
// Size textBoxSize = new Size(Math.Max(150, element.DesiredSize.Width), Math.Max(30, element.DesiredSize.Height));
// Point location = new Point((this.Width - textBoxSize.Width) / 2,
// (textBoxSize.Height - this.Height) / 2);
// child.Arrange(new Rect(location, textBoxSize));
//}
TextBox child = _Visuals[0] as TextBox;
Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
child.Arrange(adornedElementRect);
return base.ArrangeOverride(finalSize);
}
// Overriding the default ArrangeOverride and MeasureOverride allows a control to be diplayed in the VisualCollection.
protected override Size MeasureOverride(Size constraint)
{
_Textbox.Measure(constraint);
return _Textbox.DesiredSize;
}
protected override Visual GetVisualChild(int index)
{
return _Visuals[index];
}
// A common way to implement an adorner's rendering behavior is to override the OnRender
// method, which is called by the layout system as part of a rendering pass.
protected override void OnRender(DrawingContext drawingContext)
{
Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
// Some arbitrary drawing implements.
SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green)
{
Opacity = 0.2
};
Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
double renderRadius = 5.0;
// Draw a circle at each corner.
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius);
drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius);
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(EditSelectedItemAdorner), new PropertyMetadata(string.Empty));
}
}
<TreeView Grid.Row="2" Grid.Column="2" Grid.RowSpan="4" Width="400"
ItemsSource="{Binding SpecialityTree}"
>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type tree:SpecialityTreeItem}" ItemsSource="{Binding Offices}" >
<TextBlock Text="{Binding Title}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type tree:OfficeTreeItem}" ItemsSource="{Binding Doctors}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type tree:DoctorTreeItem}">
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding LastName}" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</TreeView.ItemContainerStyle>
<i:Interaction.Behaviors>
<b:ConsultantTreeViewBehavior
EditSelectedItem="{Binding IsEditing}"
SelectedItem="{Binding SelectedTreeItem, Mode=TwoWay}"
Text="{Binding EditingResult, Mode=OneWayToSource}"
/>
</i:Interaction.Behaviors>
namespace Doctor_Desk.Views.Behaviors
{
public class ConsultantTreeViewBehavior : Behavior<TreeView>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
if (AssociatedObject != null)
{
AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
}
}
private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
SelectedItem = e.NewValue;
}
#region SelectedItem Property
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(ConsultantTreeViewBehavior), new UIPropertyMetadata(null, OnSelectedItemChanged));
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is TreeViewItem item)
{
item.SetValue(TreeViewItem.IsSelectedProperty, true);
}
}
#endregion
#region [EditSelectedItem]
public bool EditSelectedItem
{
get { return (bool)GetValue(EditSelectedItemProperty); }
set { SetValue(EditSelectedItemProperty, value); }
}
private EditSelectedItemAdorner _Adorner;
public AdornerLayer myAdornerLayer { get; set; }
// Using a DependencyProperty as the backing store for EditSelectedItem. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EditSelectedItemProperty =
DependencyProperty.Register("EditSelectedItem", typeof(bool), typeof(ConsultantTreeViewBehavior), new PropertyMetadata(false, OnEditSelectedItem));
private static void OnEditSelectedItem(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue)
{
var d = sender as ConsultantTreeViewBehavior;
var h = d.AssociatedObject as TreeView;
TreeViewItem tvi = h
.ItemContainerGenerator
.ContainerFromItemRecursive(h.SelectedItem);
if (tvi is UIElement myItem)
{
d._Adorner = new EditSelectedItemAdorner(myItem, (IConsultantTreeItem)h.SelectedItem);
// Must have BindingMode.TwoWay for the Adorner to update this ConsultantTreeViewBehavior.
var bindingText = new Binding
{
Source = d,
Path = new PropertyPath(TextProperty),
Mode = BindingMode.TwoWay
};
// The TextProperty binds the Text from the EditSelectedItemAdorner to the ConsultantManagerViewModel.
BindingOperations.SetBinding(d._Adorner, EditSelectedItemAdorner.TextProperty, bindingText);
d.myAdornerLayer = AdornerLayer.GetAdornerLayer(myItem);
d.myAdornerLayer.Add(d._Adorner);
}
}
}
#endregion
#region[Text - xaml binding]
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(ConsultantTreeViewBehavior), new PropertyMetadata(string.Empty,
(s, e) =>
{
}));
#endregion
}
}