问题描述:

I tried UIElement.InvalidateVisual but it didn't work. I read about this INotifyPropertyChanged but I don't know exactly how it is used, not to mention I'm talking about User Controls, it seems I need to use that INotifyPropertyChanged to all of the controls.

I'm having trouble refreshing combo boxes changes and data grid changes, what I did is to close and reopen the form but I don't want that approach because it seems sluggish in re-executing every user control constructors.

this is my code:

if (linkSource.ToString() == "BreedList.xaml")

{

this.InvalidateVisual();

}

else if (linkSource.ToString() == "PetTypeList.xaml")

{

this.InvalidateVisual();

}

else if (linkSource.ToString() == "IrritantList.xaml")

{

this.InvalidateVisual();

}

网友答案:

This answer is an attempt to give you a peek into how WPF applications work, but I am not offering to teach you WPF... that is your job.

As @HighCore correctly pointed out, there is no UserControl.Refresh method. In a WPF Application (using MVVM), we create custom class objects called view models that contain the data and functionality that the UserControls and/or Windows (called views) need to provide. They are paired by setting the view DataContext property to an instance of the relevant view model. There are several ways to do that... this is just one way:

public SomeView()
{
    ...
    DataContext = new SomeViewModel();
}

Now, all of the controls declared in SomeView have access to all of the (public) properties and ICommands from the SomeViewModel class. We use them with data binding:

<TextBox Text="{Binding SomePropertyInSomeViewModel}" ... />  

...

<ListBox ItemsSource="{Binding SomeCollectionPropertyInSomeViewModel}" />  

During initialisation of the SomeViewModel class, we might see something like this:

public SomeViewModel()
{
    SomeCollectionPropertyInSomeViewModel = SomeDataSource.GetSomeCollection();
}

This gets the data from any external data source and populates the SomeCollectionPropertyInSomeViewModel property. In turn, the SomeCollectionPropertyInSomeViewModel property provides the collection items for the ListBox. So finally, to answer your question, How do we refresh the data?, the answer is to call the methods that get the data again. So you could do something like this:

public void RefreshData()
{
    SomeCollectionPropertyInSomeViewModel = SomeDataSource.GetSomeCollection();
}

Ok, so here ends today's lesson. For any further questions, please refer to the proper Microsoft documentation on MSDN. For follow up information, please see the Introduction to WPF page on MSDN.

网友答案:

To add to previous answer: there are two ways to create "SomeViewModel". In both ways it should notify about a property change.

1) Use a DependencyObject. This is a standard WPF way, all UserControls are also DependencyObjects. Taken from here, read full explanation: http://wpftutorial.net/DependencyProperties.html

    public class SomeViewModel : DependencyObject
    {
        // Dependency Property
        public static readonly DependencyProperty CurrentTimeProperty =
             DependencyProperty.Register("CurrentTime", typeof(DateTime),
             typeof(SomeViewModel), new FrameworkPropertyMetadata(DateTime.Now));

        // .NET Property wrapper
        public DateTime CurrentTime
        {
            get { return (DateTime)GetValue(CurrentTimeProperty); }
            set { SetValue(CurrentTimeProperty, value); }
        }
    }

When CurrentTime changes everybody which is registered ( for example using {Binding CurrentTime} in XAML ) will get a notification and "Refresh"

2) Use INotifyPropertyChanged interface. Here's a small example: http://msdn.microsoft.com/en-us/library/vstudio/ms229614(v=vs.100).aspx

There are some differences between this approaches ( for example you can't create binding to INotifyPropertyChanged property ). Please read here: http://www.codeproject.com/Articles/62158/DependencyProperties-or-INotifyPropertyChanged INotifyPropertyChanged vs. DependencyProperty in ViewModel

Good luck!

相关阅读:
Top