简体   繁体   English

如何使用 ComboBox、Enum 和 DependencyProperty 实现 WinUI 3 UserControl

[英]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 haveMainWindow.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 haveMainWindow.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 haveExampleControl.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.我搜索了ComboBoxDependencyPropertyEnum ,并找到了一些匹配项,例如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在用户控件中,对于enumsx: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:BindTwoWay绑定的问题, OneWayOneTimex:Bind的绑定似乎没问题。 And not an issue if binding to strings rather than enums.如果绑定到字符串而不是枚举,这不是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM