我正在為我的一個控制元件撰寫自定義裝飾器。我想向這個裝飾器添加一個背景關系選單,并用列舉的值填充它的一個專案。我知道如何在 XAML 中進行這樣的系結:
<ContextMenu>
<MenuItem Header="Color" ItemsSource={Binding Source={local:EnumBindingSource {x:Type local:MyColorEnum}, ReturnStrings=True}, Mode=OneTime}/>
</ContextMenu>
其中 EnumBindingSource 是我為此目的撰寫的自定義 MarkupExtension:
public class EnumBindingSource : MarkupExtension
{
private Type enumType;
public Type EnumType
{
get => enumType;
set
{
if (enumType != value)
{
if (value != null)
{
Type type = Nullable.GetUnderlyingType(value) ?? value;
if (!type.IsEnum)
throw new ArgumentException("Type must be an enum type");
}
enumType = value;
}
}
}
public bool ReturnStrings { get; set; }
public EnumBindingSource() { }
public EnumBindingSource(Type enumType)
{
this.enumType = enumType;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
// code to turn enum values into strings, not relevant to the problem
}
}
在這種情況下,我無法在 XAML 中創建系結,因為裝飾器沒有任何 XAML 代碼。我想改為在 C# 中創建系結,我嘗試這樣做:
internal class MyAdorner : Adorner, INotifyPropertyChanged
{
(...)
public MyAdorner(UIElement adornedElement) : base(adornedElement)
{
(...)
ContextMenu contextMenu = new ContextMenu();
MenuItem color = new MenuItem()
{
Header = "Color"
};
color.SetBinding(ItemsControl.ItemsSourceProperty, new Binding()
{
Source = new EnumBindingSource(typeof(MyColorEnum))
{
ReturnStrings = true
},
Mode = BindingMode.OneTime
});
contextMenu.Items.Add(color);
this.ContextMenu = contextMenu;
}
}
但這失敗了,它什么也沒創造。不幸的是,我在網上找到的任何關于在代碼中創建系結的資源都沒有為這種特殊情況提供足夠的資訊。
一如既往,非常感謝任何幫助。
uj5u.com熱心網友回復:
當你寫這個:
ItemsSource="{Binding Source={local:MyMarkup}}"
xaml 引擎不會直接將MyMarkup
物件放在源屬性中。它使用as 引數
呼叫該MarkupExtension.ProvideValue
方法。
回傳的物件是.IProvideValueTarget
Source
所以等效的 C# 代碼是:
var ebs = new EnumBindingSource(typeof(MyColorEnum)) { ReturnStrings = true };
color.SetBinding(ItemsControl.ItemsSourceProperty, new Binding()
{
Source = ebs.ProvideValue(null), // provide a IServiceProvider is hard
Mode = BindingMode.OneTime
});
順便說一句,您不需要系結,因為源不會更改(MarkupExtension
不會覆寫INotifyPropertyChanged
)。
然后你可以寫:
<ContextMenu>
<MenuItem Header="Color" ItemsSource="{local:EnumBindingSource {x:Type local:MyColorEnum}, ReturnStrings=True}" />
</ContextMenu>
此處提供MRE的作業演示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/494731.html