How do I bind DateTime as DepedencyProperty of a DependencyObject so that it will show up in a textbox?

瘦欲@ 提交于 2019-12-13 04:28:12

问题


I want to learn how to use Dependency Objects and Properties. I have created this class,

    public class TestDependency : DependencyObject
    {
        public static readonly DependencyProperty TestDateTimeProperty =
            DependencyProperty.Register("TestDateTime", 
            typeof(DateTime), 
            typeof(TestDependency), 
            new PropertyMetadata(DateTime.Now));

        public DateTime TestDateTime
        {
            get { return (DateTime) GetValue(TestDateTimeProperty); }
            set { SetValue(TestDateTimeProperty, value); }
        }
    }

The window class is like this

public partial class MainWindow : Window
{
    private TestDependency td;
    public MainWindow()
    {
        InitializeComponent();
        td = new TestDependency();
        td.TestDateTime = DateTime.Now;
    }
}

Now I want to use it to show a the current DateTime in the TextBlock which updates itself every second, by adding this to a grid

<Grid>
    <TextBlock Text="{Binding TestDateTime,ElementName=td}" Width="200" Height="200"/>
</Grid>

I can see the TextBlock, but there is no Date Time value in it at all. What am I doing wrong?


回答1:


First of all if you want to update the display time once a second your going to need a timer to trigger an update. A DispatchTimer works works well for that.

public class TestDependency : DependencyObject
{
    public static readonly DependencyProperty TestDateTimeProperty =
        DependencyProperty.Register("TestDateTime", typeof(DateTime), typeof(TestDependency),
        new PropertyMetadata(DateTime.Now));

    DispatcherTimer timer;

    public TestDependency()
    {
        timer = new DispatcherTimer(new TimeSpan(0,0,1), DispatcherPriority.DataBind, new EventHandler(Callback), Application.Current.Dispatcher);
        timer.Start();

    }

    public DateTime TestDateTime
    {
        get { return (DateTime)GetValue(TestDateTimeProperty); }
        set { SetValue(TestDateTimeProperty, value); }
    }

    private void Callback(object ignore, EventArgs ex)
    {
        TestDateTime = DateTime.Now;
    }

}

Next we need to modify the XAML so it binds properly to the updated dependency object.

<Window.DataContext>
    <local:TestDependency/>
</Window.DataContext>
<Grid>
    <TextBlock Text="{Binding TestDateTime}" />
</Grid>

Since we set the DataContext in XAML you can actually delete all of the code behind code in the MainWindow constructor.




回答2:


If you just want to show some values in your TextBlock, you don't need a Dependency Object here. Try something like this:

public partial class MainWindow : Window
{
    public DateTime Test
    { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        this.Test = DateTime.Now;
    }
}

<Grid>
    <TextBlock Text="{Binding Path=Test,RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor}}"></TextBlock>
</Grid>

Here I am not showing the code which can update the value every second. I just want to clarify that this is not the right situation to use Dependency Property. Of course you can use Dependency Property to do this. But Dependency Object and Dependency Property can offer you some extension functionality such as Data Binding. But it doesn't mean that you need to use a Dependency Object or Dependency Property as the source of the Data Binding.



来源:https://stackoverflow.com/questions/14663265/how-do-i-bind-datetime-as-depedencyproperty-of-a-dependencyobject-so-that-it-wil

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!