Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用lambda语句在WPF中初始化UIPropertyMetaData_C#_Wpf_Dependency Properties - Fatal编程技术网

C# 如何使用lambda语句在WPF中初始化UIPropertyMetaData

C# 如何使用lambda语句在WPF中初始化UIPropertyMetaData,c#,wpf,dependency-properties,C#,Wpf,Dependency Properties,我知道这很基本,但我不明白。我只想使用lambda操作符将依赖属性破折号初始化为双集合 正确的语法是什么 多谢各位 public static readonly DependencyProperty DashesProperty = DependencyProperty.Register("Dashes", typeof(DoubleCollection), typeof(CustomTextBlock), new UIPropertyMetadata(

我知道这很基本,但我不明白。我只想使用lambda操作符将依赖属性
破折号
初始化为双集合

正确的语法是什么

多谢各位

public static readonly DependencyProperty DashesProperty =
        DependencyProperty.Register("Dashes", typeof(DoubleCollection), typeof(CustomTextBlock),
        new UIPropertyMetadata(
             () =>
            {
                DoubleCollection d = new DoubleCollection();
                d.Add(4);
                d.Add(4);
                return d;
            }
     ));

不幸的是,这是不可能的。您只能提供值,不能提供值工厂。解决方法是在构造函数中初始化属性:

public CustomTextBlock()
{
    Dashes = new DoubleCollection {4, 4};
}

实际上,我刚刚意识到,由于
DoubleCollection
Freezable
,因此只要调用
Freeze
,将
DoubleCollection
的实例作为默认值(正如Rohit Vats所建议的那样)就可以工作。你可以这样做:

public static readonly DependencyProperty DashesProperty =
        DependencyProperty.Register("Dashes", typeof(DoubleCollection), typeof(CustomTextBlock),
        new UIPropertyMetadata(CreateDefaultDashes()));

private static DoubleCollection CreateDefaultDashes()
{
    var dashes = new DoubleCollection { 4, 4 };
    dashes.Freeze();
    return dashes;
}
这使得集合不可变,这意味着它可以在
CustomTextBlock
的实例之间安全地共享


好的,实际上默认值似乎是自动冻结的,所以您不需要做任何特殊的事情。它作为默认值是安全的,因为当它被冻结时,它变得不可变。

不幸的是,这是不可能的。您只能提供值,不能提供值工厂。解决方法是在构造函数中初始化属性:

public CustomTextBlock()
{
    Dashes = new DoubleCollection {4, 4};
}

实际上,我刚刚意识到,由于
DoubleCollection
Freezable
,因此只要调用
Freeze
,将
DoubleCollection
的实例作为默认值(正如Rohit Vats所建议的那样)就可以工作。你可以这样做:

public static readonly DependencyProperty DashesProperty =
        DependencyProperty.Register("Dashes", typeof(DoubleCollection), typeof(CustomTextBlock),
        new UIPropertyMetadata(CreateDefaultDashes()));

private static DoubleCollection CreateDefaultDashes()
{
    var dashes = new DoubleCollection { 4, 4 };
    dashes.Freeze();
    return dashes;
}
这使得集合不可变,这意味着它可以在
CustomTextBlock
的实例之间安全地共享

好的,实际上默认值似乎是自动冻结的,所以您不需要做任何特殊的事情。它作为默认值是安全的,因为它在冻结时是不可变的。

首先,您应该避免在DP元数据中传递引用类型的默认值,因为这将在您不打算传递的包含类的所有实例中共享

比方说,您声明了CustomTextBlock的两个实例,然后这两个实例都将引用同一个列表,并且列表中的任何修改对这两个实例都是透明的。除非您从构造函数或其他地方显式设置它


不管怎样,如果你还想要它,这里是如何做到的:

new UIPropertyMetadata(new DoubleCollection() { 4, 5 })

更新

如果在元数据中传递默认值,则DoubleCollection将自动冻结,即在这种情况下,您无法从集合中添加/删除

var dashesCollection = new CustomTextBlock().Dashes.Add(5); // Will throw exception.
但是,如果从构造函数显式设置,则不会将其标记为冻结,并且可以从集合中添加/删除项

var dashesCollection = new CustomTextBlock().Dashes.Add(5); // Works fine.
所以,本质是在构造函数中而不是在DP标识符的元数据中设置值

首先,您应该避免在DP元数据中传递引用类型的默认值,因为这将在您不打算传递的包含类的所有实例中共享

比方说,您声明了CustomTextBlock的两个实例,然后这两个实例都将引用同一个列表,并且列表中的任何修改对这两个实例都是透明的。除非您从构造函数或其他地方显式设置它


不管怎样,如果你还想要它,这里是如何做到的:

new UIPropertyMetadata(new DoubleCollection() { 4, 5 })

更新

如果在元数据中传递默认值,则DoubleCollection将自动冻结,即在这种情况下,您无法从集合中添加/删除

var dashesCollection = new CustomTextBlock().Dashes.Add(5); // Will throw exception.
但是,如果从构造函数显式设置,则不会将其标记为冻结,并且可以从集合中添加/删除项

var dashesCollection = new CustomTextBlock().Dashes.Add(5); // Works fine.


所以,本质是在构造函数中设置值,而不是在DP标识符的元数据中设置值

@RohitVats,DoubleCollection是一种类型…@RohitVats,DoubleCollection是一种类型…所以…根本不使用UIPropertyMetadata吗?@AlanWayne,不,在这种情况下您不需要它,因为您无法提供合理的默认值。谢谢。我是新来的。我也想将此标记为一个答案,但我似乎不能标记多个答案。@AlanWayne,不,只能标记一个。。。如果你喜欢这个答案,你可以随时向上投票。所以……根本不使用UIPropertyMetadata?@AlanWayne,不,在这种情况下你不需要它,因为你无法提供合理的默认值。谢谢。我是新来的。我也想将此标记为一个答案,但我似乎不能标记多个答案。@AlanWayne,不,只能标记一个。。。如果您喜欢这个答案,您可以随时向上投票。我认为OP已经意识到引用类型DPs的问题,否则他不会试图使用lambda而不是直接传递值。@RohitVats谢谢。为什么我不打算在所有实例中共享一个常量?@AlanWayne,因为它不是一个真正的常量!DoubleCollection类是可变的:您可以添加、删除或替换其中的项。这些更改将由
CustomTextBlock
的所有实例共享,这可能不是您想要的…@AlanWayne-对于值类型,它确实有意义。但对于引用类型,则不是这样。假设您有两个CustomTextBlock实例,您想在第一个实例的破折号集合中添加5,但在第二个实例中也会添加5,因为它们在内部引用的是同一个集合实例。@Thomas-我刚刚测试了如果在元数据中传递了默认值,默认情况下,它是冻结的,不需要显式调用Freeze()。我认为OP已经意识到引用类型DPs的问题,否则他不会试图使用lambda而不是直接传递值。@RohitVats谢谢。为什么我不打算在所有实例中共享一个常量?@AlanWayne,因为它不是一个真正的常量!DoubleCollection类是可变的:您可以添加、删除或替换其中的项。这些更改将由
CustomTextBlock
的所有实例共享,这可能不是您想要的…@AlanWayne-对于值类型,它确实有意义。