小编bwa*_*all的帖子

如何从xaml访问UserControl中的按钮?

在工作中,我有几个页面,每个页面都有相同位置的按钮,并具有相同的属性.每个页面也有细微差别.为此,我们创建了一个userControl模板并将所有按钮放入其中,然后将该用户控件应用于所有页面.但是,现在很难访问按钮并从每个页面的xaml修改它们,因为它们位于页面上的UserControl内..... 我如何优雅地访问每个页面的按钮?

我尝试过的:

  1. 目前,我们绑定了一堆依赖属性.我不喜欢这个选项,因为我有很多按钮,需要控制这些按钮上的很多属性.结果是数以百计的依赖属性,当我们需要改变某些东西时,它会变得非常混乱.

  2. 另一种方法是使用样式.我一般都喜欢这种方法,但由于这些按钮位于另一个控件内部,因此很难对其进行修改,并且模板一次只适用于一个按钮.

  3. Adam Kemp发布了关于让用户在这里插入自己的按钮的消息,这就是我目前正在试图修改/修改的方法.不幸的是,我无法访问Xamarin.

虽然模板代码运行时插入,模板正确地更新按钮.如果我在MyButton Setter中放置一个断点,我可以看到该实际上是一个空按钮,而不是我在主窗口中指定的那个.我该如何解决?

这是一些简化的代码:

我的模板UserControl的xaml:

<UserControl x:Class="TemplateCode.Template"
     x:Name="TemplatePage"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     mc:Ignorable="d"
     d:DesignHeight="350"
     d:DesignWidth="525"
     DataContext="{Binding RelativeSource={RelativeSource Self}}"
     Background="DarkGray">

     <Grid>
          <Button x:Name="_button" Width="200" Height="100" Content="Template Button"/>
     </Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

我的模板UserControl的代码背后:

using System.Windows.Controls;

namespace TemplateCode
{
    public partial class Template : UserControl
    {
        public static Button DefaultButton;

        public Template()
        {
             InitializeComponent();
        }

        public Button MyButton
        {
            get
            {
                 return _button;
            }
            set
            {
                _button = value; //I get …
Run Code Online (Sandbox Code Playgroud)

c# wpf xaml user-controls nested-attributes

11
推荐指数
2
解决办法
1939
查看次数

如何制作UI-MarkupExtension

我有一个简单的UIElement,我想将其转换为MarkupExtension:

[MarkupExtensionReturnType(typeof(FrameworkElement))]
public class PinkRectangle : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    { 
        return new Rectangle {Height = 100, Width = 300, Fill = Brushes.HotPink };
    }
}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,它的效果都很好。唯一的例外是在列表中:

<local:WindowEx x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.winfx/200x/xaml"
    xmlns:local="clr-namespace:WpfApp1"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    MyProperty="{Binding local:PinkRectangle}"> <!--this one works.-->
    <local:WindowsEx.MyList>
        <!--<Grid/> If I comment this line in, it works-->
        <local:PinkRectangle/>
    </local:WindowsEx.MyList>

    <ContentPresenter Content="{Binding MyProperty}"/>
</local:WindowEx>
Run Code Online (Sandbox Code Playgroud)

Collection Syntax中,它说:

如果属性的类型是集合,则不需要在标记中将推断的集合类型指定为对象元素。而是将要成为集合中项目的元素指定为property元素的一个或多个子元素。每个此类项目在加载过程中都会被评估为一个对象,然后通过调用隐式集合的Add方法将其添加到集合中。

但是,xaml将上面的语法解释为,MyList = PinkRectangle而不是MyList.Add(PinkRectangle)But。但是,如果我先放入Grid,它会正确调用MyList.Add()。两种情况下告诉xaml调用MyList.Add()的正确语法是什么?

这是其余的代码,以创建一个最小的,可复制的示例

namespace WpfApp1
{
    // I …
Run Code Online (Sandbox Code Playgroud)

.net c# wpf xaml markup-extensions

7
推荐指数
1
解决办法
206
查看次数

异步 void lambda 表达式

一个快速的谷歌搜索会告诉你尽可能避免使用async void myMethod()方法。在许多情况下,有办法使之成为可能。我的问题基本上是这个最佳实践的一个分支:

下面的 lambda 表达式的计算结果是什么?

Task.Run( async ()=> await Task.Delay(1000));
Run Code Online (Sandbox Code Playgroud)

如果它变成了,async Task那么我们将遵循最佳实践。

但是如果它评估为async void呢?

c# async-await generic-lambda

3
推荐指数
1
解决办法
722
查看次数