我有一个依赖属性定义如下。它在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从父usercontrol传递为
<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 );
}
}
}
ChildForeColor属性在parentusercontrol的构造函数中设置如下。
作为构造函数参数传递的值为蓝色。
public Parentusercontrol(System.Drawing.Color ForeColor)
{
ChildForeColor = Color.FromRgb(ForeColor.R, ForeColor.B, ForeColor.G);
}
但是,Parent控件的InitializeComponent();
xaml.cs会清除依赖属性的值,因此只使用默认值。
我是否必须更改依赖属性的定义?如何解决这个错误?
答案 0 :(得分:1)
这对我来说非常好!
ChildControl
我给了UserControl一个Xaml的名字,即
<UserControl ... (all normal namespaces)... x:Name="Child">
<Border>
<Border.Background>
<SolidColorBrush Color="{Binding ForeColor, ElementName=child}"/>
</Border.Background>
</Border>
</UserControl>
属性“ForeColor”是您自己定义的依赖属性。此控件也可以完美地运行。
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#Class外观如下
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);
}
}
}
我已经为_ChildForeColor分配了一个仅用于测试的值,但这不是必需的。但请注意,如果运行NotifyPropertyChanged事件,则在InitializeComponent()之前不会发生这种情况。我想这是因为还没有任何东西被初始化来听取变化。因此,您有2个选项。删除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>
正如我所说,这对我来说非常好,并且所有属性都保留了它们的价值。
答案 1 :(得分:0)
可能的解决方案:
确保父级的childForeColor具有分配给它的颜色,尤其是在使用普通属性时。
如果您在Parent控件中使用普通属性,请确保在Initialize(我猜您已订阅)之后更改颜色时调用INotifyPropertyChange
或许使用FrameworkPropertyMetadata,然后添加标志AffectsRender - 不要认为这是问题,但值得一试
使用绑定模式 - 虽然我不认为这是真正的问题
如果您正在使用2个x控件,其中1个属性最有可能从其他属性继承,请使用Inherited属性 - http://msdn.microsoft.com/en-us/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());
并查看是否会改变它。