isakavis
isakavis

Reputation: 785

WPF Binding to a property in second ViewModel

How do I get the text bound to txtMessage from the second view model? When I had only one view model, the text was working fine. It does not work anymore when I moved the actual download code to second view model. Am I missing something? Any help appreciated.

Xaml:

<DockPanel DockPanel.Dock="Top">
    <TextBlock x:Name="txtMessage" DockPanel.Dock="Top" Margin="5" Text="{Binding viewModel1.Message}" />
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="5,5">
    <ProgressBar Width="300" Visibility="{Binding IsDownloading, Converter={converter:VisibilityConverter}}" IsIndeterminate="True" />
<Button Content="Cancel" />
</StackPanel>
</DockPanel>
<Button Content="Download" Width="120" Margin="0,0,5,0" Name="btnSubmit" Click="btnSubmit_Click" />

CodeBehind:

public partial class DownloadWindow: Window
    {
        DownloadWindowViewModel viewModel = new DownloadWindowViewModel();

        public DownloadWindow()
        {
            InitializeComponent();
            this.DataContext = viewModel;
        }

        private void btnSubmit_Click(object sender, RoutedEventArgs e)
        {
            viewModel.IsDownloading = true;
            viewModel.Download();

        }

    }

viewModel:

public class DownloadWindowViewModel: INotifyPropertyChanged
    {

        Thread downloadThread;
        public DownloadViewModel viewModel1;

        public DownloadWindowViewModel()
        {
            viewModel1 = new DownloadViewModel();
        }

        private bool _isDownloading; = false;

        public bool IsDownloading
        {
            get 
            { 
                return _isDownloading; 
            }
            set 
            { 
                _isDownloading; = value;
                OnPropertyChanged("IsDownloading");
            }
        }

        public void Download()
        {
            viewModel1.Download();

        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }


    }

viewModel1:

public class DownloadViewModel: INotifyPropertyChanged
    {
        Thread _thread;

        public void Download()
        {
            ThreadStart threadStart = delegate()
            {
                StartDownload();
            };
            _thread = new Thread(threadStart);
            _thread.IsBackground = true;
            _thread.Start();

        }

        private void StartDownload()
        {
            for (int i = 10; i < 1500; i++)
            {
                Thread.Sleep(5000);
                Message = "Downloading " + i.ToString();
            }
        }

        private string _message = "";

        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                if (_message != value)
                {
                    _message = value;
                    OnPropertyChanged("Message");
                }

            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }

Upvotes: 0

Views: 2269

Answers (1)

k.m
k.m

Reputation: 31454

Your viewModel1 has to be a property, and it's a field at the moment. Change it to:

public DownloadViewModel viewModel1 { get; set; }

Explanation why such restriction exists, can be found here (primarily due to notification/verifications mechanisms simply not working for fields):

Upvotes: 2

Related Questions