Вы также могли бы рассмотреть то, что Вы пытаетесь сделать - при хорошем форматировании текста, который ввели люди, Вы могли бы полагать, что фильтр как Скидка с цены позволил Вашим пользователям отформатировать свой текст, не открывая кучу проблем, которая является HTML. Вы знаете, как он здесь при Переполнении стека.
Я попытался использовать CompositeCollection
, предложенный Кентом Бугартом, но мне не удалось заставить его работать из-за ошибки в wpf , не позволяющей использовать привязку RelativeSource в CollectionContainer
.
Решение, которое я использовал, - иметь RecentFiles
в собственном подменю, привязанном к Collection через Свойство ItemsSource
.
Я действительно хотел иметь список в меню «Файл», но я думаю, что это лучший вариант ...
Править
На основе этой статьи Я создал собственный и более общий MenuItemList
:
public class MenuItemList : Separator {
#region Private Members
private MenuItem m_Parent;
private List<MenuItem> m_InsertedMenuItems;
#endregion
public MenuItemList() {
Loaded += (s, e) => HookFileMenu();
}
private void HookFileMenu() {
m_Parent = Parent as MenuItem;
if (m_Parent == null) {
throw new InvalidOperationException("Parent must be a MenuItem");
}
if (ParentMenuItem == m_Parent) {
return;
}
if (ParentMenuItem != null) {
ParentMenuItem.SubmenuOpened -= _FileMenu_SubmenuOpened;
}
ParentMenuItem = m_Parent;
ParentMenuItem.SubmenuOpened += _FileMenu_SubmenuOpened;
}
private void _FileMenu_SubmenuOpened(object sender, RoutedEventArgs e) {
DataBind();
}
#region Properties
public MenuItem ParentMenuItem { get; private set; }
#region ItemsSource
/// <summary>
/// ItemsSource Dependency Property
/// </summary>
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(MenuItemList),
new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(OnItemsSourceChanged)));
/// <summary>
/// Gets or sets a collection used to generate the content of the <see cref="MenuItemList"/>. This is a dependency property.
/// </summary>
public IEnumerable ItemsSource {
get { return (IEnumerable) GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
/// <summary>
/// Handles changes to the ItemsSource property.
/// </summary>
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
((MenuItemList) d).OnItemsSourceChanged(e);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes to the ItemsSource property.
/// </summary>
protected virtual void OnItemsSourceChanged(DependencyPropertyChangedEventArgs e) {
DataBind();
}
#endregion
#region ItemContainerStyle
/// <summary>
/// ItemsContainerStyle Dependency Property
/// </summary>
public static readonly DependencyProperty ItemContainerStyleProperty =
DependencyProperty.Register("ItemContainerStyle", typeof(Style), typeof(MenuItemList),
new FrameworkPropertyMetadata((Style) null));
/// <summary>
/// Gets or sets the <see cref="System.Windows.Style"/> that is applied to the container element generated for each item. This is a dependency property.
/// </summary>
public Style ItemContainerStyle {
get { return (Style) GetValue(ItemContainerStyleProperty); }
set { SetValue(ItemContainerStyleProperty, value); }
}
#endregion
#endregion
private void DataBind() {
RemoveMenuItems();
InsertMenuItems();
}
private void RemoveMenuItems() {
if (m_InsertedMenuItems != null) {
foreach (var menuItem in m_InsertedMenuItems) {
ParentMenuItem.Items.Remove(menuItem);
}
}
}
private void InsertMenuItems() {
if (ItemsSource == null) {
return;
}
if (ParentMenuItem != null) {
m_InsertedMenuItems = new List<MenuItem>();
int iMenuItem = ParentMenuItem.Items.IndexOf(this);
foreach (var item in ItemsSource) {
var menuItem = new MenuItem();
menuItem.DataContext = item;
menuItem.Style = ItemContainerStyle;
ParentMenuItem.Items.Insert(++iMenuItem, menuItem);
m_InsertedMenuItems.Add(menuItem);
}
}
}
}
Он далек от совершенства, но у меня он работает. Не стесняйтесь комментировать ...
«Странное смещение» - это MenuItem
. Родительский MenuItem
уже создает для вас дочерний MenuItem
, но ваш DataTemplate
добавляет второй. Попробуй это:
Попробуйте вместо этого использовать HierarchicalDataTemplate с внутренним ContentPresenter. Взгляните на этот SO-ответ для получения более подробной информации .