我正在努力在WPF中创建可重用的自定义控件(而不是用户控件)。我在Themes / Generic.xaml文件中创建了XAML,并在控件的CS文件中设置了“lookless”功能:
AddressField.cs
using ...;
namespace MyNamespace
{
[TemplatePart(Name = AddressField.ElementAddress1TextBox, Type = typeof(TextBox))]
public class AddressField : Control
{
private const String ElementAddress1TextBox = "PART_Address1TextBox";
public AddressEntity Address
{
get { return (AddressEntity)GetValue(AddressProperty); }
set { SetValue(AddressProperty, value); }
}
public static readonly DependencyProperty AddressProperty =
DependencyProperty.Register("Address", typeof(AddressEntity), typeof(AddressField), new UIPropertyMetadata(null, new PropertyChangedCallback(OnAddressPropertyChangedCallback)));
static AddressField()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AddressField), new FrameworkPropertyMetadata(typeof(AddressField)));
}
}
}
主题\ Generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
>
<Style TargetType="{x:Type local:AddressField}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:AddressField}">
<StackPanel>
<Grid x:Name="StandardView">
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Height" Value="17" />
<Setter Property="Margin" Value="3,3,3,3" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Height" Value="23" />
<Setter Property="Margin" Value="3,3,3,3" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Address 1, Address2-->
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Text="Address:" TextWrapping="NoWrap" />
<TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="8" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" MinWidth="300"
x:Name="PART_Address1TextBox" Text="{Binding Path=Address1}" />
</Grid>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Form.xaml
<Window x:Class="NIC.BackOffice.Casino.RegistrationEntryForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:nic="clr-namespace:MyNamespace;assembly=MyStuff">
<Canvas>
<nic:AddressField Canvas.Left="10" Canvas.Top="10"
x:Name="OfficeAddressField" Address={Binding Path=OAddress} />
</Canvas>
</Window>
Form.cs
using ...;
namespace MyNamespace
{
public partial class Form : Window
{
public Form()
{
InitializeComponent();
OAddress = new AddressEntity("1234 Testing Lane");
}
public AddressEntity OAddress { get; set; }
}
}
更新:先前的代码是我之前代码的更新(删除了很多绒毛只是为了得到一个例子)。虽然,由于某种原因,即使我将OAddress的绑定设置为AddressField对象,也永远不会更新Address(在OfficeAddressField中)。
答案 0 :(得分:1)
您无需刷新DataContext
。实际上,您的控件不应该使用它。将Address
设为DependencyProperty
,然后在控件的模板中使用TemplateBinding
:
<TextBox Text="{TemplateBinding Address.Address1}"/>
答案 1 :(得分:0)
当地址dp发生变化时,您应该考虑提出一个事件。