wpf MVVM путаница - PullRequest
       2

wpf MVVM путаница

3 голосов
/ 09 апреля 2011

Последние пару дней я смотрел на MVVM и думал, что попробую простой пример обновления текстового поля со временем.Однако у меня возникли проблемы с тем, чтобы обернуть голову вокруг этого.У меня есть два проекта в моем решении. Один я вызываю TimeProvider, который сейчас просто возвращает событие Datetime, а другой - E. В конце концов я буду использовать TimeProvider, чтобы предоставить гораздо больше информации, но сначала я хочу понять кое-что простое.,Может кто-нибудь, пожалуйста, скажите мне, почему я не получаю графический интерфейс для обновления.

namespace E.TimeProvider
{
    public interface ITimeSource
    {
        void Subscribe();

        event Action<Time> TimeArrived;
    }
}
namespace E.TimeProvider
{
    public class Time
    {
        private DateTime _earthDate;

        public Time()
        {

        }

        public Time(DateTime earthDate)
        {
            this._earthDate = earthDate;
        }

        public DateTime EarthDate
        {
            get { return _earthDate; }
            set { _earthDate = value; }
        }
    }
}

namespace E.TimeProvider
{
    public class TimeSource : ITimeSource
    {
        private const int TIMER_INTERVAL = 50;

        public event Action<Time> TimeArrived;

        private bool subscribe;

        public TimeSource()
        {
            subscribe = false;
            Thread timeGenerator = new Thread(new ThreadStart(GenerateTimes));
            timeGenerator.IsBackground = true;
            timeGenerator.Priority = ThreadPriority.Normal;
            timeGenerator.Start();
        }

        public void Subscribe()
        {
            if (subscribe)
                return;

            subscribe = true;
        }

        private void GenerateTimes()
        {
            while (true)
            {
                GenerateAndPublishTimes();
                Thread.Sleep(TIMER_INTERVAL);
            }
        }

        private void GenerateAndPublishTimes()
        {
            DateTime earthDate = DateTime.Now;
            Time time = new Time(earthDate);
            TimeArrived(time);
        }
    }
}

Тогда у меня есть мой проект E xaml

<Window x:Class="E.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="200" xmlns:my="clr-namespace:Exiled" WindowStyle="None" WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
    <Grid>
        <my:TimeControl HorizontalAlignment="Left" x:Name="timeControl1" VerticalAlignment="Top" Height="300" Width="200" />
    </Grid>
</Window>

<UserControl x:Class="E.TimeControl"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="200" Background="Black" Foreground="White">
    <Grid>
        <TextBlock Height="41" HorizontalAlignment="Left" Margin="12,31,0,0"  Text="{Binding Path=EarthTime}"  VerticalAlignment="Top" Width="176" FontSize="35" TextAlignment="Center" />
    </Grid>
</UserControl>

, а остальные

namespace E
{
    public class TimeControlViewModel : DependencyObject
    {
        private readonly ITimeSource _source;


        public ObservableCollection<TimeViewModel> Times { get; set; }

        public TimeControlViewModel()
        {
            this.Times = new ObservableCollection<TimeViewModel>();
        }

        public TimeControlViewModel(ITimeSource source)
        {
            this.Times = new ObservableCollection<TimeViewModel>();

            _source = source;
            _source.TimeArrived += new Action<Time>(_source_TimeArrived); 
        }

        public void Subscribe()
        {
            _source.Subscribe();
        }

        void _source_TimeArrived(Time time)
        {
            TimeViewModel tvm = new TimeViewModel();
            tvm.Time = time;
        }   
    }
}

namespace E
{
    class SubscribeCommand
    {
        private readonly TimeControlViewModel _vm;

        public SubscribeCommand(TimeControlViewModel vm)
        {
            _vm = vm;
        }

        public void Execute(object parameter)
        {
            _vm.Subscribe();
        }
    }
}

namespace E
{
    public class TimeViewModel : DependencyObject
    {
        public TimeViewModel()
        {

        }

        public Time Time
        {
            set
            {
                this.EarthDate = value.EarthDate;
            }
        }

        public DateTime EarthDate
        {
            get { return (DateTime)GetValue(DateProperty); }
            set { SetValue(DateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Date.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DateProperty =
            DependencyProperty.Register("EarthDate", typeof(DateTime), typeof(TimeViewModel), new UIPropertyMetadata(DateTime.Now));
    }
}

Ответы [ 2 ]

2 голосов
/ 09 апреля 2011

У вас есть несколько вопросов здесь:

  1. Вы не видите обновления, потому что DataContext вашего Window или UserControl не установлен на экземпляр TimeViewModel, который вы создаете.
  2. Как правило, экземпляры ViewModel не должны быть объектами DependencyObjects. Вместо этого реализуйте INotifyPropertyChanged. Это не позволяет им зависеть от WPF, но все же позволяет им правильно работать с MVVM.

Я бы рекомендовал прочитать подробное введение в MVVM, такое как , которое я написал здесь . В частности, вам нужно понять, как работает шаблонирование и DataContext, чтобы правильно использовать привязку.

0 голосов
/ 09 апреля 2011

Для начала похоже, что вы привязаны к EarthTime:

Text="{Binding Path=EarthTime}"

но само свойство называется EarthDate

public DateTime EarthDate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...