A Petrov
A Petrov

Reputation: 474

How do I update a grid in my XAML UI?

I am using C# WPF, VS2013.

Here is my MainWindow class definition:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    public void addData(){
    //this is the method I want to access
    }
...
}

I want to use the addData method from another class. Theoretically it should be something like:

public class DataEntry
{
     public void randomMethod()
     {
         MainWindow.addData(); //this doesn't work - the addData method can not be accessed
     }
}

If I do it like this:

public class DataEntry
{
     public void randomMethod()
     {
         MainWindow mw = new MainWindow()
         mw.addData();
     }
}

I can access it, but then I end up with two MainWindows.

If I change the method definition of addData() to public static void addData() then it can be accessed from the outer class (DataEntry), but then I can not access my TextBox from the addData() method.

Upvotes: 0

Views: 213

Answers (2)

That's a reasonable intuitive assumption about how you'd do it, and it would be correct in a lot of environments, but not in XAML. In XAML you do things very differently: You put your data in something the grid knows how to examine, you show that to the grid, and the grid handles the details of populating itself.

It's declarative. You say what you want: "I want this list of stuff to be in the grid". Let the grid fiddle around with incrementing i for the millionth time.

The data that goes in the grid should be in an ObservableCollection (we'll call it GridItems), which should be a public property of your view model class. If you don't have a view model, it's time to write one -- we'll call it MainWindowViewModel. It doesn't necessarily have to do a whole lot. That's where the data lives, and the functions that load and save it. The View -- your MainWindow -- is in charge of showing the data to the user, and exposing menu items or buttons to load and save etc. But MainWindow just exposes those controls, and binds them to Commands exposed by the view model. MainWindow knows what the commands are called, but he has no knowledge of what they mean.

The MainWindowViewModel instance is assigned to MainWindow.DataContext. The DataGrid's ItemsSource property should be bound to GridItems.

<DataGrid ItemsSource="{Binding GridItems}" ...>
    <!-- columns, etc. -->
</DataGrid>

When somebody adds or removes items on viewmodel.GridItems, the grid will be notified and will update itself accordingly.

This is the standard way things are done in XAML, and once you get used to it, it's pretty slick.

For the view model to expose lists of things is easy: Just use ObservableCollection. For non-list properties, you'll need to inherit your view model class from INotifyPropertyChanged, and implement that interface (see Google for that, it's not a big deal). So say you have a CurrentFileName property in your view model...

private String _currentFileName;
public String CurrentFileName {
    get { return _currentFileName; }
    set {
        _currentFileName = value;
        //  If you've implemented this properly, this will send out a 
        //  notification that this property has changed. Any binding  
        //  in MainWindow that's bound to this property will get that 
        //  and act on it. 
        OnPropertyChanged("CurrentFileName");
    }
}

Also, I'd like to concur that a tutorial would be a good idea, if you're new enough to programming that creating a new instance of MainWindow seems like a plausible way to update the old one.

Upvotes: 2

Servy
Servy

Reputation: 203829

Rather than having your business logic know about, access, and manipulate the UI based on some value that it computes, just return the value from the method instead. Leave it up tot he UI that calls that class to take the return value from the method and do whatever it needs to do with it, such as setting a textbox value.

In addition to simply being easier, this has the advantage of greatly reducing the coupling of your application. Your business logic now doesn't need to be used with this particular UI. You could create an entirely different presentation of this logic without needing to duplicate it; you can test it without needing to access the UI; it can be written, maintained, and reasoned about in isolation rather than complicating it with a bunch of UI logic.

Upvotes: 0

Related Questions