У меня есть собственный элемент управления GroupBox, который может содержать дочерние элементы, однако дочерним элементам сложно выполнять такие действия, как RelativeSource или Bind to ElementName. Если во время работы программы я удалю ссылку на GroupBox и сочетание клавиш Ctrl-Z, обновление приведет к правильной оценке привязок, однако при следующей загрузке программы возникнет та же проблема.
Это GroupBox.cs
using MaterialDesignThemes.Wpf;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Markup;
namespace Commercial_Asset_Maintenance_Tool.Controls
{
[ContentProperty("CustomContent")]
public class GroupBox : Control
{
public object CustomContent
{
get { return GetValue(CustomContentProperty); }
set { SetValue(CustomContentProperty, value); }
}
public static readonly DependencyProperty CustomContentProperty =
DependencyProperty.Register("Content", typeof(object), typeof(GroupBox), new PropertyMetadata(null));
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(string), typeof(GroupBox), new PropertyMetadata(""));
public string HeaderStringFormat
{
get { return (string)GetValue(HeaderStringFormatProperty); }
set { SetValue(HeaderStringFormatProperty, value); }
}
public static readonly DependencyProperty HeaderStringFormatProperty =
DependencyProperty.Register("HeaderStringFormat", typeof(string), typeof(GroupBox), new PropertyMetadata(null));
private static List _emptyActionButtonList = new List();
public List ActionButtons
{
get { return (List)GetValue(ActionButtonsProperty); }
set { SetValue(ActionButtonsProperty, value); }
}
public static readonly DependencyProperty ActionButtonsProperty =
DependencyProperty.Register("ActionButtons", typeof(List), typeof(GroupBox), new PropertyMetadata(_emptyActionButtonList));
public FrameworkElement InformationContent
{
get { return (FrameworkElement)GetValue(InformationContentProperty); }
set { SetValue(InformationContentProperty, value); }
}
public static readonly DependencyProperty InformationContentProperty =
DependencyProperty.Register("InformationContent", typeof(FrameworkElement), typeof(GroupBox), new PropertyMetadata(null));
public bool IsExpandable
{
get { return (bool)GetValue(IsExpandableProperty); }
set { SetValue(IsExpandableProperty, value); }
}
// Using a DependencyProperty as the backing store for IsExpandable. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsExpandableProperty =
DependencyProperty.Register("IsExpandable", typeof(bool), typeof(GroupBox), new PropertyMetadata(false));
public bool IsExpanded
{
get { return (bool)GetValue(IsExpandedProperty); }
set { SetValue(IsExpandedProperty, value); }
}
// Using a DependencyProperty as the backing store for IsExpanded. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsExpandedProperty =
DependencyProperty.Register("IsExpanded", typeof(bool), typeof(GroupBox), new PropertyMetadata(true));
public bool ShowSelectionBorder
{
get { return (bool)GetValue(ShowSelectionBorderProperty); }
set { SetValue(ShowSelectionBorderProperty, value); }
}
// Using a DependencyProperty as the backing store for ShowSelectionBorder. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ShowSelectionBorderProperty =
DependencyProperty.Register("ShowSelectionBorder", typeof(bool), typeof(GroupBox), new PropertyMetadata(true));
public GroupBox() : base()
{
SetCurrentValue(ActionButtonsProperty, new List());
}
static GroupBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GroupBox), new FrameworkPropertyMetadata(typeof(GroupBox)));
}
public override void OnApplyTemplate()
{
//base.OnApplyTemplate();
//Apply bindings and events
ContentControl headerContent = GetTemplateChild("HeaderContent") as ContentControl;
headerContent?.SetBinding(ContentControl.ContentProperty, new Binding("Header") { Source = this });
headerContent?.SetBinding(ContentControl.ContentStringFormatProperty, new Binding("HeaderStringFormat") { Source = this });
ContentControl mainContent = GetTemplateChild("MainContent") as ContentControl;
mainContent?.SetBinding(ContentControl.ContentProperty, new Binding("CustomContent") { Source = this });
PopupBox popupContent = GetTemplateChild("PopupContent") as PopupBox;
popupContent?.SetBinding(PopupBox.PopupContentProperty, new Binding("InformationContent") { Source = this });
popupContent?.SetBinding(PopupBox.VisibilityProperty, new Binding("InformationContent") { Source = this, Converter = new Converters.NotNullVisibilityConverter() });
ItemsControl actionsContent = GetTemplateChild("ItemsContent") as ItemsControl;
actionsContent?.SetBinding(ItemsControl.ItemsSourceProperty, new Binding(".") { Source = this.ActionButtons });
Grid rootControl = GetTemplateChild("RootElement") as Grid;
rootControl?.SetBinding(Grid.DataContextProperty, new Binding("DataContext") { Source = this });
ToggleButton expandingButton = GetTemplateChild("ExpanderToggleButton") as ToggleButton;
expandingButton?.SetBinding(ToggleButton.IsCheckedProperty, new Binding("IsExpanded") { Source = this });
FrameworkElement isExpandableElement = GetTemplateChild("IsExpandableElement") as FrameworkElement;
isExpandableElement?.SetBinding(FrameworkElement.IsEnabledProperty, new Binding("IsExpandable") { Source = this });
FrameworkElement showSelectionElement = GetTemplateChild("ShowSelectionElement") as FrameworkElement;
showSelectionElement?.SetBinding(FrameworkElement.IsEnabledProperty, new Binding("ShowSelectionBorder") { Source = this });
FrameworkElement isExpandedElement = GetTemplateChild("IsExpandedElement") as FrameworkElement;
isExpandedElement?.SetBinding(FrameworkElement.IsEnabledProperty, new Binding("IsExpanded") { Source = this });
}
}
}
Буду очень признателен за любые идеи, поскольку я просто не могу добиться какого-либо прогресса в решении этой проблемы.
Я также пробовал TemplateBinding внутри XAML вместо того, чтобы делать это в выделенном коде, но проблема по-прежнему остается той же.
Привязки работают нормально вне GroupBox, единственная проблема заключается в том, что они являются дочерними элементами GroupBox.
Моя основная мысль заключается в том, что дочерний элемент GroupBox неправильно добавляется в визуальное дерево при первой загрузке. Или он загружается до полной инициализации визуального дерева, но я не знаю, как это изменить.
У меня есть собственный элемент управления GroupBox, который может содержать дочерние элементы, однако дочерним элементам сложно выполнять такие действия, как RelativeSource или Bind to ElementName. Если во время работы программы я удалю ссылку на GroupBox и сочетание клавиш Ctrl-Z, обновление приведет к правильной оценке привязок, однако при следующей загрузке программы возникнет та же проблема. Это GroupBox.cs [code]using MaterialDesignThemes.Wpf; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Markup;
namespace Commercial_Asset_Maintenance_Tool.Controls { [ContentProperty("CustomContent")] public class GroupBox : Control { public object CustomContent { get { return GetValue(CustomContentProperty); } set { SetValue(CustomContentProperty, value); } } public static readonly DependencyProperty CustomContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(GroupBox), new PropertyMetadata(null));
public string Header { get { return (string)GetValue(HeaderProperty); } set { SetValue(HeaderProperty, value); } } public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(GroupBox), new PropertyMetadata(""));
public string HeaderStringFormat { get { return (string)GetValue(HeaderStringFormatProperty); } set { SetValue(HeaderStringFormatProperty, value); } } public static readonly DependencyProperty HeaderStringFormatProperty = DependencyProperty.Register("HeaderStringFormat", typeof(string), typeof(GroupBox), new PropertyMetadata(null));
private static List _emptyActionButtonList = new List(); public List ActionButtons { get { return (List)GetValue(ActionButtonsProperty); } set { SetValue(ActionButtonsProperty, value); } } public static readonly DependencyProperty ActionButtonsProperty = DependencyProperty.Register("ActionButtons", typeof(List), typeof(GroupBox), new PropertyMetadata(_emptyActionButtonList));
public FrameworkElement InformationContent { get { return (FrameworkElement)GetValue(InformationContentProperty); } set { SetValue(InformationContentProperty, value); } } public static readonly DependencyProperty InformationContentProperty = DependencyProperty.Register("InformationContent", typeof(FrameworkElement), typeof(GroupBox), new PropertyMetadata(null));
public bool IsExpandable { get { return (bool)GetValue(IsExpandableProperty); } set { SetValue(IsExpandableProperty, value); } }
// Using a DependencyProperty as the backing store for IsExpandable. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsExpandableProperty = DependencyProperty.Register("IsExpandable", typeof(bool), typeof(GroupBox), new PropertyMetadata(false));
public bool IsExpanded { get { return (bool)GetValue(IsExpandedProperty); } set { SetValue(IsExpandedProperty, value); } }
// Using a DependencyProperty as the backing store for IsExpanded. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register("IsExpanded", typeof(bool), typeof(GroupBox), new PropertyMetadata(true));
public bool ShowSelectionBorder { get { return (bool)GetValue(ShowSelectionBorderProperty); } set { SetValue(ShowSelectionBorderProperty, value); } }
// Using a DependencyProperty as the backing store for ShowSelectionBorder. This enables animation, styling, binding, etc... public static readonly DependencyProperty ShowSelectionBorderProperty = DependencyProperty.Register("ShowSelectionBorder", typeof(bool), typeof(GroupBox), new PropertyMetadata(true));
public GroupBox() : base() { SetCurrentValue(ActionButtonsProperty, new List()); }
static GroupBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(GroupBox), new FrameworkPropertyMetadata(typeof(GroupBox))); }
public override void OnApplyTemplate() { //base.OnApplyTemplate();
//Apply bindings and events ContentControl headerContent = GetTemplateChild("HeaderContent") as ContentControl; headerContent?.SetBinding(ContentControl.ContentProperty, new Binding("Header") { Source = this }); headerContent?.SetBinding(ContentControl.ContentStringFormatProperty, new Binding("HeaderStringFormat") { Source = this });
ContentControl mainContent = GetTemplateChild("MainContent") as ContentControl; mainContent?.SetBinding(ContentControl.ContentProperty, new Binding("CustomContent") { Source = this });
PopupBox popupContent = GetTemplateChild("PopupContent") as PopupBox; popupContent?.SetBinding(PopupBox.PopupContentProperty, new Binding("InformationContent") { Source = this }); popupContent?.SetBinding(PopupBox.VisibilityProperty, new Binding("InformationContent") { Source = this, Converter = new Converters.NotNullVisibilityConverter() });
ItemsControl actionsContent = GetTemplateChild("ItemsContent") as ItemsControl; actionsContent?.SetBinding(ItemsControl.ItemsSourceProperty, new Binding(".") { Source = this.ActionButtons });
Grid rootControl = GetTemplateChild("RootElement") as Grid; rootControl?.SetBinding(Grid.DataContextProperty, new Binding("DataContext") { Source = this });
ToggleButton expandingButton = GetTemplateChild("ExpanderToggleButton") as ToggleButton; expandingButton?.SetBinding(ToggleButton.IsCheckedProperty, new Binding("IsExpanded") { Source = this });
FrameworkElement isExpandableElement = GetTemplateChild("IsExpandableElement") as FrameworkElement; isExpandableElement?.SetBinding(FrameworkElement.IsEnabledProperty, new Binding("IsExpandable") { Source = this });
FrameworkElement showSelectionElement = GetTemplateChild("ShowSelectionElement") as FrameworkElement; showSelectionElement?.SetBinding(FrameworkElement.IsEnabledProperty, new Binding("ShowSelectionBorder") { Source = this });
FrameworkElement isExpandedElement = GetTemplateChild("IsExpandedElement") as FrameworkElement; isExpandedElement?.SetBinding(FrameworkElement.IsEnabledProperty, new Binding("IsExpanded") { Source = this }); } } }
[/code] А это GroupBox.XAML [code] xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:Commercial_Asset_Maintenance_Tool.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Commercial_Asset_Maintenance_Tool" xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
[/code] И это тот случай, когда он используется [code]
[/code] Буду очень признателен за любые идеи, поскольку я просто не могу добиться какого-либо прогресса в решении этой проблемы. Я также пробовал TemplateBinding внутри XAML вместо того, чтобы делать это в выделенном коде, но проблема по-прежнему остается той же. Привязки работают нормально вне GroupBox, единственная проблема заключается в том, что они являются дочерними элементами GroupBox. Моя основная мысль заключается в том, что дочерний элемент GroupBox неправильно добавляется в визуальное дерево при первой загрузке. Или он загружается до полной инициализации визуального дерева, но я не знаю, как это изменить.