How do I Access Buttons inside a UserControl from xaml?(如何从 xaml 访问 UserControl 内的按钮?)
问题描述
在工作中,我有几个页面,每个页面的按钮都在相同的位置,并且具有相同的属性.每一页也有细微的差别.为此,我们创建了一个用户控件模板并将所有按钮放入其中,然后将该用户控件应用于所有页面.但是,现在访问按钮并从每个页面的 xaml 修改它们相当困难,因为它们位于页面上的 UserControl 内..... 我如何优雅地访问每个页面的按钮?
At work I have several pages, each with buttons in the same places, and with the same properties. Each page also has minor differences. To that end, we created a userControl Template and put all the buttons in it, then applied that user control to all the pages. However, now it's rather hard to access the buttons and modify them from each page's xaml, because they are inside a UserControl on the page..... How do I elegantly access the buttons from each page?
我的尝试:
目前,我们绑定到一堆依赖属性.我不喜欢这个选项,因为我有很多按钮,并且需要控制这些按钮的很多属性.结果是数百个依赖属性,当我们需要更改某些内容时,真的是一团糟.
Currently, we bind to a bunch of dependency properties. I don't like this option because I have a lot of buttons, and need to control a lot of properties on those buttons. The result is hundreds of dependency properties, and a real mess to wade through when we need to change something.
另一种方法是使用样式.我一般都喜欢这种方法,但是因为这些按钮在另一个控件中,所以很难修改它们,而且模板一次只能完全正确地用于一个按钮.
Another method is to use styles. I like this method generally, but because these buttons are inside another control it becomes difficult to modify them, and the template would only be exactly right for one button, at one time.
Adam Kemp 发布了关于让用户只需插入自己的按钮 这里,这是我目前正在尝试实施/修改的方法.不幸的是,我无法访问 Xamarin.
Adam Kemp posted about letting the user just insert their own button here, and this is the method I'm currently trying to impliment / modify. Unfortunately, I don't have access to Xamarin.
虽然在代码运行时插入了模板,但模板并没有正确更新按钮.如果我在 MyButton Setter 中设置断点,我可以看到 value 实际上是一个空按钮,而不是我在主窗口中分配的那个.我该如何解决这个问题?
Although the template is inserted when the code runs, the template is not updating the button correctly. If I put a breakpoint in the MyButton Setter, I can see that value is actually an empty button, rather than the one I assigned in my main window. How do I fix this?
这是一些简化的代码:
我的模板 UserControl 的 xaml:
My Template UserControl's 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>
我的模板用户控件背后的代码:
My Template UserControl's Code Behind:
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 here, but value is a blank button?!
// Eventually, I'd like to do something like:
// Foreach (property in value)
// {
// If( value.property != DefaultButton.property) )
// {
// _button.property = value.property;
// }
// }
// This way users only have to update some of the properties
}
}
}
}
现在是我要使用它的应用程序:
And now the application where I want to use it:
<Window x:Class="TemplateCode.MainWindow"
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"
xmlns:templateCode="clr-namespace:TemplateCode"
Title="MainWindow"
Height="350"
Width="525"
Background="LimeGreen"
DataContext="{Binding RelativeSource={RelativeSource Self}}" >
<Grid>
<templateCode:Template>
<templateCode:Template.MyButton>
<Button Background="Yellow"
Content="Actual Button"
Width="200"
Height="100"/>
</templateCode:Template.MyButton>
</templateCode:Template>
</Grid>
</Window>
现在是背后的代码:
Using System.Windows;
Namespace TemplateCode
{
Public partial class MainWindow : Window
{
Public MainWindow()
{
InitializeComponent();
}
}
}
虽然我想删除 template userControl 中不必要的依赖属性,但我仍然想在 button 上设置绑定来自 XAML 的属性.
While I want to remove unnecessary dependency properties in the template userControl, I'd still like to set bindings on the button's properties from the XAML.
推荐答案
另一个基于@Funk 答案的选项是在模板上制作一个内容控件而不是按钮,然后在代码中将内容控件的内容绑定到你的ButtonProperty后面:
Another Option based on @Funk's answer is to make a content control instead of a button on the template, then bind the content control's content to your ButtonProperty in the code behind:
在模板上:
<ContentControl Content={Binding myButton} Width="200" Height="100"/>
在模板代码后面:
public static readonly DependencyProperty myButtonProperty =
DependencyProperty.Register("Button", typeof(Button), typeof(Template),
new UIPropertyMetadata(new PropertyChangedCallback(ButtonChangedCallback)));
然后在主窗口上:
<Window.Resources>
<Button x:Key="UserButton"
Background="Yellow"
Content="Actual Button"
/>
</Window.Resources>
<Grid>
<templateCode:Template myButton="{StaticResource UserButton}"/>
</Grid>
这样做的好处是 Visual Studio 足够智能,可以在设计时显示此代码,并且总体上代码更少.
The nice thing about this is that Visual Studio is smart enough to show this code at design time, as well as having less code overall.
您可以在内容控件或默认样式中为您的按钮设置固定的东西(如位置、字体和颜色),然后只修改按钮所需的部分.
You can set things constant things (like location, font, and coloring) for your button either on the content control or in a default style, and then modify just the parts you need for you button.
这篇关于如何从 xaml 访问 UserControl 内的按钮?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何从 xaml 访问 UserControl 内的按钮?
基础教程推荐
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- MS Visual Studio .NET 的替代品 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01