2010-08-11 181 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改變時引發一個事件。