在工作中,我有几个页面,每个页面都有相同位置的按钮,并具有相同的属性.每个页面也有细微差别.为此,我们创建了一个userControl模板并将所有按钮放入其中,然后将该用户控件应用于所有页面.但是,现在很难访问按钮并从每个页面的xaml修改它们,因为它们位于页面上的UserControl内..... 我如何优雅地访问每个页面的按钮?
我尝试过的:
目前,我们绑定了一堆依赖属性.我不喜欢这个选项,因为我有很多按钮,需要控制这些按钮上的很多属性.结果是数以百计的依赖属性,当我们需要改变某些东西时,它会变得非常混乱.
另一种方法是使用样式.我一般都喜欢这种方法,但由于这些按钮位于另一个控件内部,因此很难对其进行修改,并且模板一次只适用于一个按钮.
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) 我有一个简单的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) 一个快速的谷歌搜索会告诉你尽可能避免使用async void myMethod()方法。在许多情况下,有办法使之成为可能。我的问题基本上是这个最佳实践的一个分支:
下面的 lambda 表达式的计算结果是什么?
Task.Run( async ()=> await Task.Delay(1000));
Run Code Online (Sandbox Code Playgroud)
如果它变成了,async Task那么我们将遵循最佳实践。
但是如果它评估为async void呢?