绑定在第一次加载时不起作用

时间:2018-03-07 19:42:23

标签: wpf binding

我在UserControl中有一个按钮。我在这里提供的代码很简单,只是为了说明你的情况。这就是为什么我包含第二个按钮以允许有意义的用户交互。 UserControl xaml代码如下:

<UserControl x:Class="WpfControlLibrary1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfControlLibrary1"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" x:Name="MyUserControl">
    <Grid>       
        <Button Name="btSelectColor"  ToolTip="Select color" Width="23" Height="23"  BorderBrush="#FF070707" Background="{Binding Mode=OneWay, ElementName=MyUserControl, Path=CurrentColorBrush}"></Button>
        <Button Name="btChangeColor"  ToolTip="For change color for testing" Width="120" Height="23" Margin="90,166,90,110" Click="btChangeColor_Click">Test color changing</Button>
    </Grid>
</UserControl>

ElementName属性值是MyUserControl,它与UserControl x:Name属性的值相同。 Path值是CurrentColorBrush,它是后面代码中定义的依赖项属性的包装,如下所示:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WpfControlLibrary1
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {

            InitializeComponent();
            CurrentColorBrush = new SolidColorBrush(Color.FromArgb(1, 150, 250, 150));

        }

        public static readonly DependencyProperty currentColorBrushProperty = DependencyProperty.Register("CurrentColorBrush", typeof(SolidColorBrush), typeof(UserControl1));

        public SolidColorBrush CurrentColorBrush
        {
            get
            {
                return (SolidColorBrush)GetValue(currentColorBrushProperty);
            }
            set
            {
                SetValue(currentColorBrushProperty, value);
            }
        }
        private void btChangeColor_Click(object sender, RoutedEventArgs e)
        {
            CurrentColorBrush = new SolidColorBrush(Color.FromArgb(1, System.Convert.ToByte(CurrentColorBrush.Color.R - 20), 15, 15));
        }

    }
}

我使用以下语句在UserControl的构造函数中为此属性设置了一个默认值:

CurrentColorBrush = new SolidColorBrush(Color.FromArgb(1, 150, 250, 150));

问题在于,当显示包含Usercontrol的窗口时,按钮背景不是UserControl构造函数中定义的默认颜色。即使单击第二个按钮,第一个按钮的背景也保持不变。更奇怪的是,如果在运行时检查可视树,您可以看到预期值已到位但您从未以图形方式看到更改。 UserControl位于单独的WPF用户控件库项目中。我正在使用Visual Studio 2017。

EDITED ********

Aybe提出的解决方案给了我一个线索。代码有效,与我的相似。所以,我开始寻找差异,我意识到我的代码中CurrentBrush的初始值是从Color定义的SolidColorBrush。此颜色是根据没有特殊标准选择的RGBA值定义的。事实是,当我使用(像Aybe那样)刷子的标准值,如Brushes.DarkCyan,一切都运行良好。也许我提供的RGB值会创建一个对Background属性无效的颜色。我不知道是否有这种限制,但我的代码的行为可能指向这样的东西。我用Google搜索,但我找不到任何关于此事的内容。你有什么想法吗?

2 个答案:

答案 0 :(得分:0)

尝试使用依赖项属性创建的特定重载,以允许您指定默认值

here is an article about the dp's default value

答案 1 :(得分:0)

以下是您提到的每个案例中最小的可行示例:

窗口:

<Window
    x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApp1"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <StackPanel>
        <local:UserControl1 x:Name="uc1" />
        <Button
            Background="{Binding ElementName=uc1, Path=CurrentBrush}"
            Click="Button_Click"
            Content="Button1" />
    </StackPanel>
</Window>

窗口:

using System.Windows;
using System.Windows.Media;

namespace WpfApp1
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // this will work but beware that button focus hides it
            // move the mouse away from button to see that it worked
            uc1.CurrentBrush = Brushes.PaleVioletRed;
        }
    }
}

控制:

<UserControl
    x:Class="WpfApp1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid>
        <TextBlock Text="Hello, world !" />
    </Grid>
</UserControl>

控制:

using System.Windows;
using System.Windows.Media;

namespace WpfApp1
{
    public partial class UserControl1
    {
        // the default value is specified in the metadata, below
        // I changed it from default(Brush) to Aqua
        public static readonly DependencyProperty CurrentBrushProperty = DependencyProperty.Register(
            "CurrentBrush", typeof(Brush), typeof(UserControl1), new PropertyMetadata(Brushes.Aqua));

        public UserControl1()
        {
            InitializeComponent();

            // this will override the default value above
            CurrentBrush = Brushes.DarkCyan;
        }

        public Brush CurrentBrush
        {
            get => (Brush) GetValue(CurrentBrushProperty);
            set => SetValue(CurrentBrushProperty, value);
        }
    }
}

注意:注意Visual Studio的XAML设计器,有时候没有反映出更改,即更喜欢Expression Blend的XAML设计器