2

I'm totally new to WPF so heres my code:

 <DataGrid x:Name="dgVarConfig" ItemsSource="{Binding varConfigList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="10,59,0,0" VerticalAlignment="Top" Height="403" Width="1278" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" HeadersVisibility="Column">

            <DataGrid.Columns>
                <DataGridTextColumn  Width="auto" Header="Match Ausdruck" Binding="{Binding match_expression}"></DataGridTextColumn>
            </DataGrid.Columns>
</DataGrid>

My Files: MainWindow.xaml, MainController.cs, VarConfigDAO.cs

the varConfigDAO.cs returns the list to the MainController, and the MainController.cs returns it do MainWindows.xaml.

This is the VarConfig.cs:

 public class VarConfig
    {
        public int id { get; set; }
        public String group { get; set; }
        public String machine { get; set; }
        public String match_expression { get; set; }
        public String variant_new_1 { get; set; }
        public String calc_formula_1 { get; set; }
        public String variant_new_2 { get; set; }
        public String calc_formula_2 { get; set; }
    }

It works if i set the itemssource programmaticly:

dgVarConfig.Itemssource = mainController.loadVarConfigList();

But thats not what i want because i want to update the list via the grid (insert, delete, update lines => Mode=TwoWay)

Any clue how i can fill the itemssource via xaml?

0

2 Answers 2

7

Create a view model class with a property that holds a collection of VarConfig objects. The collection should notify the view about changes (like added or removed elements). An appropriate collection type would therefore be ObservableCollection:

public class ViewModel
{
    public ObservableCollection<VarConfig> VarConfigList { get; }
        = new ObservableCollection<VarConfig>();
}

Set the DataContext of your UI (e.g. your MainWindow) to an instance of the view model, for example in code behind in the MainWindow constructor like this:

public MainWindow()
{
    InitializeComponent();

    var viewModel = new ViewModel();
    // fill viewModel.VarConfigList

    DataContext = viewModel;
}

Bind to the VarConfigList property in XAML. It is not necessary to set Mode=TwoWay or UpdateSourceTrigger=PropertyChanged, as the ItemsSource property is only bound one-way (the DataGrid - or any other ItemsControl - never sets it):

<DataGrid ItemsSource="{Binding VarConfigList}" ...>
    ...
</DataGrid>

Finally, if you also want the UI to react on changes of the individual VarConfig properties, it should implement the INotifyPropertyChanged interface:

public class VarConfig : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private int id;
    public int Id
    {
        get { return id; }
        set
        {
            id = value;
            OnPropertyChanged(nameof(Id));
        }
    }

    // similar code for the other properties
}

Note the casing. It's widely accepted to write C# property names in PascalCase.

Sign up to request clarification or add additional context in comments.

7 Comments

i did it this way. the datagrid is filled now. but what are the advantages? if the list changes i need to reset the datacontext? i dont really get it. and how can i fill the VarConfigList if theres a private set?
You don't need to reset the DataContext if the list changes. When elements are added or removed from the list, this will be notified by the ObservableCollection. If you want to create a new instance of the List, the ViewModel class should also implement INotifyPropertyChanged and notify about the VarConfigList property. Search the web for MVVM. It's an architectural pattern for creating UI application, which is perfectly supported by WPF.
and how do i fill the VarConfigList if theres a private set?
viewModel.VarConfigList.Add(new VarConfig { ... });. The setter is private means you can't replace the entire collection, but you can still access the existing one. But of course that is just a detail, the setter might as well be public.
ok, thanks. and is there a way to update the collection via the grid?
|
0

You are going to have to set the DataContext for your DataGrid to whatever object has varConfigList in it. Then, the DataGrid will be able to see varConfigList and do it's stuff. You don't give a lot of code, so it I can't see what you are after, but I'm going to make some guesses, and see if they help.

There are a few ways to do it. I take it the DataGrid is in your MainWindow, so it will normally inherit its DataContext from there; but you can also set it individually.

Here is one possible way:

MainWindow

<Window ...>
    <DataGrid ... ItemsSource={Binding VarConfigList} ... />
</Window>

public partial class MainWindow : Window
{
  ...
  MainWindow()
  {
       InitializeComponent();
       this.DataContext = new MainController();
  }
}

MainController

class MainControler 
{
    private var _varConfigList;
    public var VarConfgList { get { return _varConfigList; } }
    ...

    public MainControler()
    { 
       // set stuff up 
    }
}

Then your next problem is how to get the DataGrid to treat VarConfigList as you want, but that is another story.

In my limited experience, sorting out the DataContexts has been the biggest obstacle in learning WPF.

2 Comments

Don't call it controller. It's a view model.
I agree, Clemens, and I like your reply more than mine. I'm going to leave mine up, because sometimes two forms of words can help someone understand. I think, once you get your head around DataContexts, the use of MVVM is much clearer (but that might just be me).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.