2010-08-11 146 views
1

我正在WPF中创建一个可重用的自定义控件(不是用户控件)。我创建了XAML在主题/ Generic.xaml文件,我安装该控件的CS文件中的 “无外观” 功能:WPF:依赖属性和DataContext

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; } 
    } 
} 

更新:现有的代码是从我以前的代码的更新(除去洛塔绒毛只是踏踏实实地一个例子)。虽然由于某种原因,地址(在OfficeAddressField中)永远不会更新,即使我将OAddress绑定到AddressField对象。

回答

1

您无需刷新DataContext。事实上,你的控制不应该使用它。让Address一个DependencyProperty,然后在你的控件模板使用TemplateBinding

<TextBox Text="{TemplateBinding Address.Address1}"/> 
+0

我不知道,我在我的代码做出正确的改变。到目前为止,我已经改变了:AddressEntity作为DependencyProperty从DependencyObject和Address1继承。然后,我将Address(从AddressField中)转换为DependencyProperty。这些东西根本没有帮助。无论更改的组合和匹配如何,我都尝试过,AddressField中的“Address”属性从来没有更新过myAddressField.Address = new Address(...);'。如果我试图使地址是数据绑定,它只是不想改变。 : -/ – 2010-08-11 16:16:53

+0

我最终使用了,这也起作用。但是,是的,TemplateBinding是我错过了... – 2010-08-11 18:39:15

0

你应该考虑在地址dp改变时引发一个事件。