[英]How to implement a WinUI 3 UserControl with ComboBox, Enum and DependencyProperty
Suppose we have假设我们有
public enum MyEnum {None, First, Second}
and in MainWindow.xaml.cs
, we have在
MainWindow.xaml.cs
中,我们有
private IList<MyEnum> _myEnums = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().ToList();
public IList<MyEnum> MyEnums => _myEnums;
public MyEnum SelectedMyEnum {get;set;}
and in MainWindow.xaml
we have在
MainWindow.xaml
我们有
<StackPanel>
<ComboBox ItemsSource="{x:Bind MyEnums}" SelectedItem="{x:Bind SelectedMyEnum, Mode=TwoWay}"/>
</StackPanel>
This works, as expected.正如预期的那样,这有效。
Now suppose we want to replace ComboBox
with a user control, ie现在假设我们想用一个用户控件替换
ComboBox
,即
<local:ExampleControl MyEnums="{x:Bind MyEnums}" SelectedMyEnum="{x:Bind SelectedMyEnum, Mode=TwoWay}"/>
So, in ExampleControl.xaml
we have所以,在
ExampleControl.xaml
我们有
<StackPanel>
<ComboBox
ItemsSource="{x:Bind MyEnums}"
SelectedItem="{x:Bind SelectedMyEnum,Mode=TwoWay}">
</ComboBox>
</StackPanel>
and in ExampleControl.xaml.cs
we have在
ExampleControl.xaml.cs
我们有
// SelectedMyEnum
public static readonly DependencyProperty SelectedMyEnumProperty =
DependencyProperty.Register(
"SelectedMyEnum",
typeof(MyEnum),
typeof(ExampleControl),
new PropertyMetadata(MyEnum.None)); // (1)
public MyEnum SelectedMyEnum
{
get { return (MyEnum)GetValue(SelectedMyEnumProperty); }
set { SetValue(SelectedMyEnumProperty, value); } // (2)
}
// MyEnums
public static readonly DependencyProperty MyEnumsProperty =
DependencyProperty.Register(
"MyEnums",
typeof(IEnumerable<MyEnum>),
typeof(ExampleControl), null
);
public IEnumerable<MyEnum> MyEnums
{
get { return (IEnumerable<MyEnum>)GetValue(MyEnumsProperty); }
set { SetValue(MyEnumsProperty, value); }
}
But this doesn't work.但这不起作用。 On startup, the
SelectedMyEnum
setter (2) is called repeatedly with the value MyEnum.None
until there is a stack overflow,启动时,
SelectedMyEnum
设置器 (2) 被重复调用,值为MyEnum.None
直到堆栈溢出,
System.StackOverflowException
HResult=0x800703E9
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
Instead of new PropertyMetadata(MyEnum.None)
in (1), I tried我试过而不是(1)中的
new PropertyMetadata(MyEnum.None)
new PropertyMetadata(MyEnum.None, OnEnumChanged)
with和
private static void OnEnumChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var control = (ExampleControl)obj;
MyEnum myVal = (MyEnum)args.NewValue;
}
but that made no difference, the function OnEnumChanged
was called repeatedly, along with the setter, with myVal == MyEnum.None
, until stack overflow.但这没有什么区别,函数
OnEnumChanged
与 setter 一起被重复调用,使用myVal == MyEnum.None
,直到堆栈溢出。
I checked the WinUI Gallery for examples of dependency properties for enums, but couldn't find any, but there were plenty of examples for double, int, and bool, eg ItemHeight in WrapPanel , I think I'm doing this right.我在WinUI 库中查看了枚举的依赖属性示例,但找不到任何示例,但有很多关于 double、int 和 bool 的示例,例如WrapPanel 中的 ItemHeight ,我认为我做对了。
I must be missing something, but can't see it.我一定错过了什么,但看不到它。 I've searched on
ComboBox
, DependencyProperty
, Enum
, and found some matches, eg Enum as a DependencyProperty of a UserControl , but I didn't find them helpful.我搜索了
ComboBox
、 DependencyProperty
、 Enum
,并找到了一些匹配项,例如Enum 作为 UserControl 的 DependencyProperty ,但我没有发现它们有帮助。 Any help is appreciated.任何帮助表示赞赏。
Environment:环境:
Microsoft Visual Studio Community 2022
Version 17.1.0
VisualStudio.17.Release/17.1.0+32210.238
Microsoft .NET Framework
Version 4.8.04161
Answered here by Roy Li - MSFT on the Microsoft Q&A site. Roy Li - Microsoft Q&A 网站上的 MSFT 在此回答。 It's related to a WinUI defect in the
x:Bind
markup extension.它与
x:Bind
标记扩展中的 WinUI 缺陷有关。 In the user control, in the case of enums
, x:Bind
doesn't work with SelectedMyEnum
, it needs to be written using Binding
as在用户控件中,对于
enums
, x:Bind
不适用于SelectedMyEnum
,它需要使用Binding
编写为
<ComboBox
ItemsSource="{x:Bind MyEnums}"
SelectedItem="{Binding SelectedMyEnum,Mode=TwoWay}">
</ComboBox>
and DataContext
set to this
.并将
DataContext
设置为this
。 In my experiments, it appears to be only an issue with x:Bind
and TwoWay
binding, OneWay
and OneTime
bindings with x:Bind
appear okay.在我的实验中,这似乎只是
x:Bind
和TwoWay
绑定的问题, OneWay
和OneTime
与x:Bind
的绑定似乎没问题。 And not an issue if binding to strings rather than enums.如果绑定到字符串而不是枚举,这不是问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.