繁体   English   中英

WPF依赖项属性绑定中断,并始终使用默认值

[英]WPF Dependency property binding breaks and always uses the default value

我有如下定义的依赖项属性。 它在Childusercontrol的xaml.cs中定义。 它始终使用RGB(255,0,0)默认值,即。 红色

public Color ForeColor
{
    get {return (Color)this.GetValue(ForeColorProperty); }
    set {this.SetValue(ForeColorProperty, value);}
}

public static readonly DependencyProperty ForeColorProperty = DependencyProperty.Register("ForeColor", typeof(Color), typeof(Childusercontrol), new PropertyMetadata(Color.FromRgb(255,0,0), OnCurrentForeColorPropertyChanged));

private static void OnCurrentForeColorPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{    
    Childusecontrol control = source as Childusecontrol;
    Color fcolor= (Color)e.NewValue;
}

该值通过父用户控件的xaml传递为

<UC:Childusercontrol ForeColor="{Binding ChildForeColor}"/>

ChildForeColor是ParentUserControl的ViewModel中Color类型的属性,定义如下。

 private Color _ChildForeColor;
    public Color ChildForeColor 
    {
    get
    {
    return _ChildForeColor ;
    }
    set
    {
    if (_ChildForeColor  != value)
    {
    _ChildForeColor  = value;
    RaisePropertyChanged(()=> ChildForeColor );
    }
    }
    }

然后,在parentusercontrol的构造函数中,如下设置ChildForeColor属性。

作为构造函数参数传递的值是blue

public Parentusercontrol(System.Drawing.Color ForeColor)
{
ChildForeColor  = Color.FromRgb(ForeColor.R, ForeColor.B, ForeColor.G);
}

但是, InitializeComponent(); 父控件的xaml.cs的值清除了依赖项属性的值,因此,仅使用默认值。

我是否需要更改依赖项属性的定义? 如何解决这个错误?

这对我来说效果很好!

  1. ChildControl

    我在Xml中给UserControl一个名称,即

     <UserControl ... (all normal namespaces)... x:Name="Child"> <Border> <Border.Background> <SolidColorBrush Color="{Binding ForeColor, ElementName=child}"/> </Border.Background> </Border> </UserControl> 

    属性“ ForeColor”是您自己定义的依赖项属性。 此控件本身也可以完美运行。

  2. ParentControl

    我做的和ChildControl一样。 即给它起个名字。

     <UserControl ... (Usual NS)... x:Name="parent"> <Border BorderThickness="2"> <local:ChildUserControl Margin="5" ForeColor="{Binding ChildForeColor, ElementName=parent}"/> <Border.BorderBrush> <SolidColorBrush Color="{Binding ChildForeColor, ElementName=parent}"/> </Border.BorderBrush> </Border> </UserControl> 

    这对于测试C#类的外观也可以正常工作,如下所示

     public ParentUserControl(System.Drawing.Color c) { InitializeComponent(); Color c2 = Color.FromRgb(cR, cG, cB); ChildForeColor = c2; } private Color _ChildForeColor = Color.FromRgb(0, 255, 0); public Color ChildForeColor { get { return _ChildForeColor; } set { if (value != _ChildForeColor) { _ChildForeColor = value; OnPropertyChanged(() => ChildForeColor); } } } 

    我已经为_ChildForeColor分配了一个仅用于测试的值,但这不是必需的。 但是请注意,如果您运行NotifyPropertyChanged事件,则该事件不会在InitializeComponent()之前发生; 我猜这是因为还没有初始化任何内容来监听更改。 因此,您有2个选择。 删除OnPropertyChanged并在InitializeComponent之前分配颜色,或使用OnPropertyChanged,但仅在InitializeComponent之后分配颜色。 第一个解决方案仍然可以使用,因为在组件进入并寻找值之前更改了属性值。

  3. 用于构造控件的窗口

    由于您分配了一个接受变量的构造函数,因此这有点棘手。 所以我的代码如下所示:

     public Control ParContent { get { return (ContentControl)GetValue(ParContentProperty); } set { SetValue(ParContentProperty, value); } } //Register Dependency ParContent Property public static readonly DependencyProperty ParContentProperty = DependencyProperty.Register("ParContent", typeof(ContentControl), typeof(MainWindow), new PropertyMetadata( )); public MainWindow() { InitializeComponent(); ParContent = new ParentUserControl(System.Drawing.Color.Blue); } 

    和在Xaml中

     <Window ...Title="MainWindow" Height="478.784" Width="736.87" x:Name="win"> <Grid> <local:ChildUserControl HorizontalAlignment="Left" Height="100" Margin="122,298,0,0" VerticalAlignment="Top" Width="100"/> <ContentControl x:Name="Parent" Content="{Binding ParContent,ElementName=win}" HorizontalAlignment="Left" Margin="106,49,0,0" VerticalAlignment="Top" Height="79" Width="93"/> </Grid> </Window> 

正如我所说的,这对我来说非常好,所有属性都保持其值。

可能的解决方案:

  1. 确保为父级的childForeColor分配了一种颜色,尤其是在使用普通属性时。

  2. 如果您在Parent控件中使用普通属性,请确保如果在初始化之后更改了颜色,则将调用INotifyPropertyChange(我猜您已经订阅了)

  3. 也许改用FrameworkPropertyMetadata,然后添加标志AffectsRender-不要以为这是问题,但值得一试

  4. 尝试使用绑定模式-尽管我也不认为这是真正的问题

  5. 如果您使用的是2个x控件,其中1个属性最有可能从另一个属性继承,请使用继承属性-http: //msdn.microsoft.com/zh-cn/library/ms753197(v=vs.110).aspx

底线,我怀疑父母的“ ChildForeColor”可能是造成问题的原因,因为乍一看,以上对我来说似乎还可以。

编辑

尝试执行以下操作。 在xaml中给您的父控件一个名称x:name =“ Parent”,然后在绑定模式下执行此操作

<UC:Childusercontrol ForeColor="{Binding ChildForeColor, ElementName="Parent"}"/>

如果问题出在绑定上,则应该解决所有绑定问题。

但是,您说“父控件的xaml.cs清除依赖项属性的值,因此,仅使用默认值。” 这表明问题不在于绑定或子控件,据我所知...

我还假设您已逐步完成代码,因此在点击此代码后

ChildForeColor  = Color.FromRgb(ForeColor.R, ForeColor.B, ForeColor.G);

ChildForeColor看起来正确,然后如果您覆盖OnInitialized()并在base.OnInitialized(e)之后评估ChildForeColor的值; 已经运行的ForeColor还是不变的?

通过这种方式,我还假设您尚未删除InitializeComponent(); 来自构造函数,以及InitializeComponent(); 在ChildForeColor = ....!之后 在您的构造函数中,您不会显示InitializeComponent()在哪里,我认为它只是为了易于阅读。

如果此时ForeColor保持不变并假定为base.OnInitialized,则它是第一个在OnInitialized中运行的方法。 然后初始化不是问题,然后替代建议是将ChildForeColor更改为适当的依赖项属性:

public Color ChildForeColor
    {
        get { return (Color)GetValue(ChildForeColorProperty); }
        set { SetValue(ChildForeColorProperty, value); }
    }

    //Register Dependency ChildForeColor Property
    public static readonly DependencyProperty ChildForeColorProperty = DependencyProperty.Register("ChildForeColor", typeof(Color), typeof(ParentControl), new FrameworkPropertyMetadata());

看看是否会改变它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM