C# WPF依赖项属性绑定中断并始终使用默认值
我有一个如下定义的依赖属性。它在Childusercontrol的xaml.cs中定义。它总是使用RGB(255,0,0)的默认值,即红色C# WPF依赖项属性绑定中断并始终使用默认值,c#,.net,wpf,xaml,prism,C#,.net,Wpf,Xaml,Prism,我有一个如下定义的依赖属性。它在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
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}"/>
在parentusercontrol的构造函数中,ChildForeColor属性设置如下
作为构造函数参数传递的值是蓝色的
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;
}
但是,InitializeComponent()父控件的xaml.cs的code>清除dependency属性的值,因此只使用默认值
是否必须更改依赖项属性的定义?如何修复此错误?可能的解决方案:
确保父对象的childForeColor具有指定的颜色,尤其是在使用普通属性时
如果在父控件中使用普通属性,请确保在初始化后更改颜色时调用INotifyPropertyChange(我猜您已经订阅了)
也许改用FrameworkPropertyMetadata,然后添加flag AffectsRender-不要认为这是问题所在,但值得一试
玩转绑定模式——尽管我也不认为这是真正的问题
如果您使用的是2个控件,其中1个属性最有可能继承自另一个控件,请使用继承的属性,而不是-
一句话,我怀疑父母的“ChildForeColor”可能是造成问题的原因,因为我乍一看,上述情况似乎没有问题
编辑
尝试执行以下操作。在xaml中,为父控件指定一个名称x:name=“parent”,然后在绑定模式下执行此操作
<UC:Childusercontrol ForeColor="{Binding ChildForeColor, ElementName="Parent"}"/>
ChildForeColor显示正确,如果覆盖OnInitialized()并在base.OnInitialized(e)之后计算ChildForeColor的值;已运行的前景色是否仍保持不变
我还假设您没有删除InitializeComponent()从构造函数中选择strong>并初始化Component();在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());
看看这是否会改变它。这对我来说非常好
儿童控制
我在Xaml中为UserControl指定了一个名称,即
<UserControl ... (all normal namespaces)... x:Name="Child">
<Border>
<Border.Background>
<SolidColorBrush Color="{Binding ForeColor, ElementName=child}"/>
</Border.Background>
</Border>
</UserControl>
我为_ChildForeColor指定了一个值,只是为了测试,但这不是必需的。但是请注意,如果运行NotifyPropertyChanged事件,则在InitializeComponent()之前不能发生此情况;我想这是因为还没有初始化任何内容来侦听更改。因此,您有两种选择。删除OnPropertyChanged并在InitializeComponent之前指定颜色,或使用OnPropertyChanged但仅在InitializeComponent之后指定颜色。第一个解决方案仍然有效,因为属性值在组件查找该值之前已更改
用于构造控件的窗口
这有点棘手,因为您已经分配了一个接受变量的构造函数。因此,我的代码如下所示:
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>
正如我所说的那样,我的工作非常好,所有属性都保持其值。您能显示更多wpf代码吗?例如,ChildForeColor的定义在哪里/如何定义?也可能是在“OnCurrentForeColorPropertyChanged”中做了什么?@DaClan它只是一个使用NotifyPropertyChanged的常规wpf属性它是一个常规依赖属性还是一个调用INotifyProperty的常规CLR属性在属性更改时发生了更改?它是如何以及何时更改的?当您在XAML中声明
时,您是否也在设置它的DataContext
?如果是这样,则ForeColor
上的绑定将不会使用父视图模型作为其绑定源。您在“ParentUserControl的ViewModel”中谈论的是ChildForeColor
属性,但在ParentUserControl构造函数中,您显然是直接在控件上设置了ChildForeColor
。那没有道理。或者你真的有两个这样的属性吗?我还没有尝试覆盖OnInitialized。你能给我一些博客帖子的链接,解释wpf用户控制的生命周期吗?在这里我只能找到初始化,加载和卸载,它们没有帮助。嗯。。。我不确定是否有链接或帖子对不起,也许这里的其他人可以提供帮助。
<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>
public ParentUserControl(System.Drawing.Color c)
{
InitializeComponent();
Color c2 = Color.FromRgb(c.R, c.G, c.B);
ChildForeColor = c2;
}
private Color _ChildForeColor = Color.FromRgb(0, 255, 0);
public Color ChildForeColor
{
get { return _ChildForeColor; }
set
{
if (value != _ChildForeColor)
{
_ChildForeColor = value;
OnPropertyChanged(() => ChildForeColor);
}
}
}
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);
}
<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>