-1

Im attempting to bind a gridView to a ObservableCollection in a Windows Store App. My problem is I get the data but the set does not seem to work

public class ValveData : INotifyPropertyChanged
{
    private string valveName;
    private decimal waterMl;
    private decimal waterEc;
    private decimal waterPh;


    public string ValveName 
    {
        get { return this.valveName; }
        set
        {
            this.valveName = value;
            this.OnPropertyChanged("ValveName");
        }
    }

    public decimal WaterMl
    {
        get { return this.waterMl; }
        set
        {
            this.waterMl = value;
            this.OnPropertyChanged("WaterMl");
        }
    }

    public decimal WaterEc
    {
        get { return this.waterEc; }
        set
        {
            this.waterEc = value;
            this.OnPropertyChanged("WaterEc"); 
        }
    }

    public decimal WaterPh
    {
        get { return this.waterPh; }
        set
        {
            this.waterPh = value;
            this.OnPropertyChanged("WaterPh");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

public class ValveDataCollection : ObservableCollection<ValveData>
{
    public ValveDataCollection() : base()
    {
        Add(new ValveData { ValveName = "Valve 1", WaterMl = 100, WaterEc = 3, WaterPh = 5 });
        Add(new ValveData { ValveName = "Valve 2" });
        Add(new ValveData { ValveName = "Valve 3" });
        Add(new ValveData { ValveName = "Valve 4" });
    }
}

and this is my Xaml

<data:ValveDataCollection x:Key="ValvesData"/>

<GridView x:Name="gw1" Grid.Row="2" ItemsSource="{StaticResource ValvesData}">
        <GridView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBox Text="{Binding ValveName, Mode=TwoWay}"/>
                    <TextBox Text="{Binding WaterMl, Mode=TwoWay}"/>
                    <TextBox Text="{Binding WaterEc, Mode=TwoWay}"/>
                    <TextBox Text="{Binding WaterPh, Mode=TwoWay}"/>
                </StackPanel>
            </DataTemplate>
        </GridView.ItemTemplate>
</GridView>

Im sure im missing something but I've been looking at this code for days and can't figure it out The string looks like it works, meaning if i have 2 textboxes linked to the ValveName String the set the string and get the data but it looks like its not working for the decimals, they get the data on startup but if you modify it in the textbox it doesn't seem to affect the variable

  • 1
    Please be more specific than "it doesn't work". – Peter Duniho Mar 06 '15 at 14:14
  • we can't debug things without enough information. – ArtOfCode Mar 06 '15 at 14:19
  • The string looks like it works, meaning if i have 2 textboxes linked to the ValveName String the set the string and get the data but it looks like its not working for the decimals, they get the data on startup but if you modify it in the textbox it doesn't seem to affect the variable – LittleDan45 Mar 06 '15 at 14:43

1 Answers1

2

The correct XAML should look like

<TextBox Text="{Binding ValveName, Mode=TwoWay}"/>

rather than

<TextBox Text="{Binding ValveName}, Mode=TwoWay"/>

Edit On a side note:

This code isn't thread safe. Between this.PropertyChanged != null and this.PropertyChanged another thread could unsubscribe and PropertyChanged becomes null.

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

Always use a local copy of the event handler!

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

This one is thread now safe

For future readers: With C# 6.0 (Visual Studio 2015) you can also use the below version, which is shorter and thread safe, using the new "Null Propagation Operator" operator.

public void OnPropertyChanged(string propertyName)
{
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Tseng
  • 61,549
  • 15
  • 193
  • 205