在 WPF 中创建可重用的用户控件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14627256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
creating a reusable user control in WPF
提问by Max
In the (fairly large) LOB application we are building with WPF for UI we have a lot of viewmodels that contain the same kind of data sub-object. For example, there are a lot of addresses
在我们使用 WPF 为 UI 构建的(相当大的)LOB 应用程序中,我们有很多包含相同类型数据子对象的视图模型。比如有很多地址
public class AddressViewModel : INotifyPropertyChanged
{
public string City {...}
public string ZipCode {...}
public string Address {...}
public string Number {...}
// INPC logic omitted
}
scattered among business objects:
分散在业务对象中:
public class CustomerViewModel : INotifyPropertyChanged
{
public string Name {...}
public AddressViewModel BillingAddress {...}
public AddressViewModel DeliveryAddress {...}
/*
...
*/
}
is it possible to build a reusable custom User Control which we can bind to any address sub-object?
是否可以构建一个可重用的自定义用户控件,我们可以将其绑定到任何地址子对象?
In a view (possibly another custom user control) designed to edit customer details we would like to put a custom control like this
在旨在编辑客户详细信息的视图(可能是另一个自定义用户控件)中,我们希望放置这样的自定义控件
<UserControl x:Class="OurApp.View.AddressEditor"
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="300" d:DesignWidth="300">
<Grid>
<TextBox x:Name="ZipCode" Text="{Binding Path=ZipCode, UpdateSourceTrigger = PropertyChanged}" Validation.ErrorTemplate="{x:Null}" HorizontalAlignment="Left" Height="23" Margin="10,19,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
<!-- other fields for the rest of AddressViewModel properties-->
</Grid>
</UserControl>
that we can simply use like this in a view bound to a CustomerViewModel instance
我们可以简单地在绑定到 CustomerViewModel 实例的视图中像这样使用
<TextBox x:Name="Name" Text="{Binding Path=Name, UpdateSourceTrigger = PropertyChanged}" Validation.ErrorTemplate="{x:Null}" />
<AddressEditor SomeProperty="{something that points to BillingAddress}" />
<AddressEditor SomeProperty="{something that points to DeliveryAddress}" />
What is the correct way to do this? We tried to point the binding to BillingAddress but we did not find a working way...
这样做的正确方法是什么?我们试图将绑定指向 BillingAddress,但我们没有找到可行的方法......
Thanks in advance for any contribution,
在此先感谢您的贡献,
回答by sacha barber
Yeah that should be very easy, either create a lookless control with DataTemplate, or just create a standard UserControl. Trick it to set its DataContextto a full Address object
是的,这应该很容易,可以使用 来创建一个无外观的控件DataTemplate,或者只是创建一个标准的 UserControl。欺骗它以将其DataContext设置为完整的 Address 对象
<local:AddressControl DataContext="{Binding BillingAddress}"/>
Which would allow your new "AddressControl" to have markup something like this
这将允许您的新“AddressControl”具有这样的标记
<StackPanel Orientation="Vertical">
<Label Content="City"/>
<TextBox Content="{Binding City}"/>
<Label Content="ZipCode"/>
<TextBox Content="{Binding ZipCode}"/>
<Label Content="ZipCode"/>
<TextBox Content="{Binding ZipCode}"/>
<Label Content="Number"/>
<TextBox Content="{Binding Number}"/>
</StackPanel>
回答by blindmeis
you can set the datacontext for your adresseditor to eg. the BillingAddress it should work as long the billingaddress has the properties you need in your usercontrol
您可以将地址编辑器的数据上下文设置为例如。BillingAddress 只要 billingaddress 在用户控件中具有您需要的属性,它就应该可以工作
<TextBox x:Name="Name" Text="{Binding Path=Name, UpdateSourceTrigger = PropertyChanged}" Validation.ErrorTemplate="{x:Null}" />
<AddressEditor DataContext="{Binding Path=BillingAddress}" />
instead of setting the datacontext its also possible to create a dependency property for your usercontrol where you can bind your BillingAddress to.
除了设置数据上下文之外,还可以为您的用户控件创建一个依赖属性,您可以将 BillingAddress 绑定到该属性。

