1

I had to rewrite my problem. The blackquoted part below is this post before the edit.

I have two properties : capacitiveCurrent and ShowProductSum. Before any changes in my MVVM application I used to bind capacitiveCurrent with a value that was set in the contructor - it was 15 always.

capacitiveCurrent is placed in a different class LineOut, code :

capacitiveCurrent property

    private double _capacitiveCurrent;
    public double CapacitiveCurrent
    {
        get { return _capacitiveCurrent; }
        set
        {
            if (_capacitiveCurrent != value)
            {
                _capacitiveCurrent = value;
                OnPropertyChanged("_capacitiveCurrent");
            }
        }
    }

The second property is placed in MainWindow.xaml.cs code:

ShowProductSum

        public double _showProductSum;
    public double ShowProductSum
    {
        get { return _showProductSum; }
        set
        {
            if (_showProductSum != value)
            {
                _showProductSum = value;
                OnPropertyChanged("ProductSum");
            }
        }
    }

The logic behing setting and getting ShowProductSum is done.. almost. But what I expect from those two properties is that I want them to show up in the ComboBox. This is what I have:

    private ObservableCollection<double> _comboBoxCapacitiveCurrent = new ObservableCollection<double>();
    public ObservableCollection<double> ComboBoxCapacitiveCurrent
    {
        get
        {
            _comboBoxCapacitiveCurrent.Clear();
            _comboBoxCapacitiveCurrent.Add(lineWy.capacitiveCurrent);
            _comboBoxCapacitiveCurrent.Add(ShowProductSum);
            return _comboBoxCapacitiveCurrent;
        }
        set
        {
            if (_comboBoxCapacitiveCurrent != value)
            {
                _comboBoxPradPojemnosciowy = value;
                OnPropertyChanged("ComboBoxCapacitiveCurrent");
            }
        }
    }
    public double SelectedItem { get; set; }

ComboBox:

      <DataGridTemplateColumn Header="Capacitive Current " HeaderStyle="{StaticResource ZwarcioweHeaderStyle}">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
         <ComboBox 
                  ItemsSource="{Binding Path=ComboBoxCapacitiveCurrent}"
                  SelectedValue="{Binding Path=SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
          >
                  </ComboBox>
         </DataTemplate></DataGridTemplateColumn.CellTemplate></DataGridTemplateColumn>

CombBox is present but nothing is in the dropdownlist of combobox.Some blank space just underneath this combobox. Everything implements INotifyPropertyChanged interface.

Thanks in advance.

I'm an absolute beginner in MVVM C#. I'm trying to bind two properties which are located in two different classes.

First property is public double capacitiveCurrent { get; set; } from one class and until then I used this property to View it with a normal binding - the initialized value was shown.

 public double productLengthShortCircuitCurrent
    {
    get { return length* capacitiveShortCircuitCurrentwithGround; }
    set { }
    } is a combination of the two `length` and `capacitiveShortCircuitCurrentwithGround` both with getters and

setters.

ComboBox is placed inside

`<DataGridTemplateColumn Header"ABC">
  <DataGridTemplateColumn.CellTemplate
   <DataTemplate>
    <ComboBox .../>`

What I'm trying to do is having those two properties listed in a ComboBox and:

  1. I need capacitiveCurrent to be editable from the View,
  1. The productLengthShortCircuitCurrent should be a sum of all the set values ( so a sum product).. should I call a function to do such and then bind it to the ComboBox?

**I've maged to set and get this property and achieved to get the ProductSum property below.. It is all about displaying the two properties in a ComboBox.

I'm really confused. Searched for an answer for two days, didn't come up with an idea. Maybe me knowledge is to shallow but... Tried to bind those two properties to an interface with something like public IConnectedProperties Categories and a private _category list with getter and setter.

Balttazarr
  • 75
  • 2
  • 11

2 Answers2

0

Put your two instances of your classes in one viewmodel class and bind it to the appropriate value. “ViewModels” are used to communicate between the Views and the Models. So put all your logic for interacting with the view in the viewmodel. Then you have to bind your viewmodel to the view and your datacontext is set on the object. If you want to bind your property in the instance you can use Instance.Property for the binding

Maybe these will help you. For basic explanation

RichyP7
  • 31
  • 5
  • 1
    Since I have Cable.cs (Model) and LineOut(Model) can this ViewModel be in the MainWindows.xaml.cs file? Maybe you could provide me with some more information about this topic, because wherever I look for an answer or some tips regarding MVVM people tend to use, for example : 'MyAppViewModel.cs' file. Is using the MainWindow.xaml.cs file a bad thing ? – Balttazarr Nov 28 '18 at 14:35
  • Yes it is. i would highly recommend using and own file. The main purpose of mvvm is the seperation between the ui-logic and the other layers. You will see the benefits of mvvm if you do some unit-testing or want to add a similar view with the same elements. Maybe look for some mvvm code on GitHub to get more Infos.[mvvmexample](https://github.com/buwaneka1/wpf-mvvm-example/tree/master/sayingHi!) – RichyP7 Dec 02 '18 at 19:10
0

Fix this in your setter:

_comboBoxPradPojemnosciowy = value; // binding will loose the instance

Use "Clear()" and "Add()". When you change the instance - binding is still looking in the old instance.

_comboBoxPradPojemnosciowy.Clear();
foreach (var item in value)
{
    _comboBoxPradPojemnosciowy.Add(item);
}

OnPropertyChanged("ComboBoxCapacitiveCurrent");

If ShowProductSum part is working, maybe this is the only thing you need to fix.

ComboBox bindings:

ItemsSource="{Binding Path=ComboItems}"   
SelectedItem="{Binding Path=SelectedItem}"

Carete properties and fields:

private ObservableCollection<double> comboItems = new ObservableCollection<double>();
public ObservableCollection<double> ComboItems{
    get
    {
        this.comboItems.Clear();
        this.comboItems.Add(prad_pojemnosciowy);
        this.comboItems.Add(iloczyn_dlugosc_pojemnościowy_prąd_zwarcia_z_ziemią);
        return this.comboItems;
    } 
    set;
}
public double SelectedItem{get;set}

Remember to notify property changed for "ComboItems" in the setters of the two properties.

Obelixx
  • 117
  • 5
  • For the ComboBox bindings that is clear for me. But I mentioned that there are two differenet classes and I want to combine one from each to the ComboBox. Where should I create those fields and properties? – Balttazarr Nov 28 '18 at 14:17
  • Fields and properties are created in the Model (where you implement INotifyPropertyChanged interfece). – Obelixx Nov 28 '18 at 14:38
  • Just to be clear - how two classes (instances?) are related? Are they in the same viewmodel? – Obelixx Nov 28 '18 at 14:45
  • No, but I did relate them in a ViewModel ( MainWindow.xaml.cs). I've put class declarations corresponding to those Two properties and then add OnPropertyChanged(). Since nothing is showing in the ComboBox , even the 'capacitiveCurrent' (I edited the post) which is initialized doesn't come up I tried to set the value with setter like - capacitiveCurrent=value; OnPropertyChanged("capacitiveCurrent"); The problem is nothing is showing up.. stackoverflow comes up in the setter. – Balttazarr Nov 29 '18 at 07:29
  • Can you provide small demo project? It is getting hard to suggest. Maybe you can put two view models in one calss and use them as one. Check this: https://stackoverflow.com/questions/17557811/two-views-one-viewmodel – Obelixx Nov 29 '18 at 13:39
  • 1
    Rewritten the post. maybe this should go better – Balttazarr Dec 05 '18 at 13:01
  • I saw your edit. The `_comboBoxPradPojemnosciowy = value; ` is actually like this because I changed all of the names to english substitutes for the sake of an english site. My private field is `_comboBoxPradPojemnosciowy` and the property `ComboBoxPradPojemnosciowy`. I've added: _comboBoxPradPojemnosciowy.Clear(); _comboBoxPradPojemnosciowy.AddRange(value); and it tells me that "the Observablecollection doesn't contain a definition for 'AddRange' " – Balttazarr Dec 06 '18 at 06:52
  • Sorry about "AddRange()". I changed it with foreach loop. – Obelixx Dec 06 '18 at 12:00
  • No changed. Still nothing showing up this. When I debug the program the Observablecollection ComboBoxCapacitiveCurrent never gets hit. Should it be published and then subscribed somewhere? – Balttazarr Dec 06 '18 at 12:26
  • How you defined your viewmodel? – Obelixx Dec 06 '18 at 13:39
  • it's a MainWindow.xaml.cs file. partial class with : MetroWindows , INotifyPropertyChanged, a couple of fields, properties ShowProductSum, Observablecollection ComboBoxCapacitiveCurrent , constructor, and methods – Balttazarr Dec 06 '18 at 13:46
  • It is not good to use MainWindow.xaml.cs file. Maybe you missed to define the connection between your view and viewmodel. You can do that by XML or in your case in "MainWindow" constructor by adding "this.DataContext = this;". – Obelixx Dec 06 '18 at 14:40
  • Well it wasn't there. nothing changed after adding suggested line – Balttazarr Dec 07 '18 at 06:44
  • Fix also the notifications. On property ShowProductSum setter you must do OnPropertyChanged("ShowProductSum"); and OnPropertyChanged("ComboBoxCapacitiveCurrent"); I made small demo of what you trying to accomplish. I'm searching now where to upload it. – Obelixx Dec 07 '18 at 07:35
  • Here it is a demo for you: http://s000.tinyupload.com/index.php?file_id=56605614478765653712 – Obelixx Dec 07 '18 at 07:47
  • Thanks for making things clear. Unfortuantelly it still doesn't work. I forgot to mention that CapacitiveCurrent is a property (get, set) in the LiniaWy class. The syntax in MainWindow.xaml.cs : public LiniaWy lineWy; ... _comboBoxPradPojemnosciowy.Add(lineWy.CapacitiveCurrent); I thought I should debug the program and see what does it show when it hits the ShowProductSum and I hover my mouse over the `linieWy.CapacitiveCurrent`. Results: lineWy.CapacitiveCurrent= 'lineWy.CapacitiveCurrent' threw an exception of type 'System.NullReferenceException' – Balttazarr Dec 07 '18 at 10:39
  • added public LiniaWy lineWy = new LiniaWy(); but now the value of CapacitiveCurrent is 0, should be 15 since it is set in the public LiniaWy constructor.. – Balttazarr Dec 07 '18 at 10:45
  • Please, post a demo with your problem. Does binding work now? – Obelixx Dec 07 '18 at 11:24
  • 1
    I managed to work this out .. I found out that RelativeSource was needed. This is the post where i got this . Since I used your code I'll mark this as answered, Thanks a lot :) – Balttazarr Dec 11 '18 at 06:36
  • Ok, thanks! But bear in mind, that MVVM is trying to divide each element in separate class/file - each of them with its own purpose. In short - your window code should not be INotifyPropertyChanged and hold binded properties. – Obelixx Dec 21 '18 at 14:03