【问题标题】:WPF: Dependency Properties and DataContextWPF:依赖属性和 DataContext
【发布时间】:2011-03-28 09:34:55
【问题描述】:

我正致力于在 WPF 中创建一个可重用的自定义控件(不是用户控件)。我在 Themes/Generic.xaml 文件中创建了 XAML,并在控件的 CS 文件中设置了“无外观”功能:

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 对象也是如此。

【问题讨论】:

    标签: c# wpf data-binding datacontext dependency-properties


    【解决方案1】:

    您应该考虑在地址 dp 更改时引发事件。

    【讨论】:

      【解决方案2】:

      您无需刷新DataContext。事实上,您的控件不应该使用它。将Address 设为DependencyProperty,然后在控件的模板中使用TemplateBinding

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

      【讨论】:

      • 我不确定我是否对我的代码进行了正确的更改。到目前为止,我已经更改:AddressEntity 继承自 DependencyObject 和 Address1 作为 DependencyProperty。然后,我将 Address(从 AddressField 中)转换为 DependencyProperty。这些东西一点用都没有。无论更改的混合和匹配,我都尝试了驻留在 AddressField 中的“地址”属性,除非执行myAddressField.Address = new Address(...);,否则永远不会更新。如果我尝试使地址成为数据绑定,它只是不想更改。 :-/
      • 我最终使用了 ` 效果也很好。但是,是的,我缺少的是 TemplateBinding...
      猜你喜欢
      • 1970-01-01
      • 2011-03-31
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      相关资源
      最近更新 更多