Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF用户控件属性未获取值_C#_.net_Wpf - Fatal编程技术网

C# WPF用户控件属性未获取值

C# WPF用户控件属性未获取值,c#,.net,wpf,C#,.net,Wpf,我试图创建一个非常简单的WPF用户控件来表示数字时钟 我希望客户端代码能够更改一些东西,例如前景文本颜色、字体等,因此我为它们创建了一些公共属性。部分代码如下所示: public partial class DigitalClock : System.Windows.Controls.UserControl { public string Color { get; set; } private Timer timer;

我试图创建一个非常简单的WPF用户控件来表示数字时钟

我希望客户端代码能够更改一些东西,例如前景文本颜色、字体等,因此我为它们创建了一些公共属性。部分代码如下所示:

    public partial class DigitalClock : System.Windows.Controls.UserControl
    {
        public string Color { get; set; }

        private Timer timer;            
        private string DisplayString { get { return DateTime.Now.ToString("dd-MM-yy HH:mm:ss"); } }

        public DigitalClock()
        {
            InitializeComponent();                    
            this.timer = new Timer();                
            this.timer.Tick += new EventHandler(UpdateClock);
            this.timer.Interval = 1000;
            this.timer.Enabled = true;
            this.timer.Start();
            UpdateClock(null, null);

            try
            {
                //exception thrown here as this.Color is null
                Color color = (Color)ColorConverter.ConvertFromString(this.Color);
                tbClock.Foreground = new SolidColorBrush(color);                                    
            }
            catch (Exception ex)
            {
                Console.WriteLine(">>>" + ex.Message);
            }
        }

        private void UpdateClock(object sender, EventArgs e)
        {
            tbClock.Text = DisplayString;
        }
    }
}
我在另一个页面上使用它,如下所示:

<CustomControls:DigitalClock color="#ff000000" />
  this.Loaded += DigitalClock_Loaded;
 void DigitalClock_Loaded(object sender, RoutedEventArgs e)
        {
                //your actions
                Color color = (Color)ColorConverter.ConvertFromString(this.Color);
        }

没有语法错误,时钟出现在屏幕上,但每当代码到达试图设置颜色的行时,我只会得到一个
对象引用未设置为对象的实例


我假设这与设置Color属性的时间点有关,因为在计时器的第一个“滴答”之后,该值不再为null。如何避免此问题?

您不应该将属性声明为CLR属性。您应该创建依赖性属性,而默认情况下,依赖性属性允许您绑定、验证和许多、更多。请查看以下内容:。在您的示例中,按如下方式处理加载的事件:

<CustomControls:DigitalClock color="#ff000000" />
  this.Loaded += DigitalClock_Loaded;
 void DigitalClock_Loaded(object sender, RoutedEventArgs e)
        {
                //your actions
                Color color = (Color)ColorConverter.ConvertFromString(this.Color);
        }

属性尚未在构造函数中绑定。

您不应将属性声明为CLR属性。您应该创建依赖性属性,而默认情况下,依赖性属性允许您绑定、验证和许多、更多。请查看以下内容:。在您的示例中,按如下方式处理加载的事件:

<CustomControls:DigitalClock color="#ff000000" />
  this.Loaded += DigitalClock_Loaded;
 void DigitalClock_Loaded(object sender, RoutedEventArgs e)
        {
                //your actions
                Color color = (Color)ColorConverter.ConvertFromString(this.Color);
        }

属性尚未绑定到构造函数中。

与其在构造函数中指定颜色,因为它将始终为空,因为在实例化对象之前不会设置属性,所以最好使用
颜色
属性的setter,使用一个backing字段


另外,请注意,在这种情况下,您应该使用依赖属性,并利用绑定。

而不是在构造函数中指定颜色,因为它将始终为空,因为在实例化对象之前不会设置属性,所以最好使用
颜色
属性的setter,使用backing字段


另外,请注意,在这种情况下,您应该使用依赖项属性,并利用绑定。

在另一个XAML文档中插入控件时,从该文档中设置的属性将在插入控件后设置,这意味着在调用构造函数时,您可能在其他XAML文档中设置的
Color
属性仍具有其默认值

要想做你想做的事,你可以:

  • 侦听控件的
    已加载
    事件(请参阅),在设置控件实例的所有属性后将调用该事件(您可能希望在此处启动计时器,并在
    已卸载
    事件中停止计时器,以确保当控件未在屏幕上实例化时,它不会滴答作响)

  • 您可以为
    Color
    属性的setter编写一个body来传播更改:

公共字符串颜色
{
设置{tbClock.前台=新的SolidColorBrush((颜色)ColorConverter.ConvertFromString(值));}
}
  • 如果要从另一个XAML文档设置颜色,还可以提供类型为
    Brush
    的属性,而不是颜色:
公共笔刷
{
获取{return tnClock.前台;}
设置{tnClock.Foreground=value;}
}
因此,在另一个XAML文档中,您可以通过让XAML解析器将颜色名称自动转换为画笔来直接设置颜色:


  • 或者更好,您可以在控件上声明依赖属性并使用数据绑定(假设此处
    tbClock
    TextBlock
    ):
公共笔刷
{
获取{return(Brush)GetValue(ClockForegroundProperty);}
set{SetValue(ClockForegroundProperty,value);}
}
public static readonly dependencProperty ClockForegroundProperty=dependencProperty.Register(“时钟前景”、typeof(画笔)、typeof(数字时钟));
公共数字钟()
{
初始化组件();
...
BindingOperations.SetBinding(tbClock、TextBlock.ForegroundProperty、新绑定
{
来源=此,
路径=新属性路径(ClockForegroundProperty)
});
}

在另一个XAML文档中插入控件时,从该文档中设置的属性将在插入控件后设置,这意味着在调用构造函数时,在另一个XAML文档中设置的
Color
属性仍有其默认值

要想做你想做的事,你可以:

  • 侦听控件的
    已加载
    事件(请参阅),在设置控件实例的所有属性后将调用该事件(您可能希望在此处启动计时器,并在
    已卸载
    事件中停止计时器,以确保当控件未在屏幕上实例化时,它不会滴答作响)

  • 您可以为
    Color
    属性的setter编写一个body来传播更改:

公共字符串颜色
{
设置{tbClock.前台=新的SolidColorBrush((颜色)ColorConverter.ConvertFromString(值));}
}
  • 如果要从另一个XAML文档设置颜色,还可以提供类型为
    Brush
    的属性,而不是颜色:
公共笔刷
{
获取{return tnClock.前台;}
设置{tnClock.Foreground=value;}
}
因此,在另一个XAML文档中,您可以通过让XAML解析器将颜色名称自动转换为画笔来直接设置颜色:


  • 或者更好,您可以在控件上声明依赖属性并使用数据绑定(假设此处
    tbClock
    TextBlock
    ):
公共笔刷
{
获取{return(Brush)GetValue(ClockForegroundProperty);}
set{SetValue(ClockForegroundProperty,value);}
}
公共静态只读从属属性时钟