haosmark
haosmark

Reputation: 1127

XAML bound property isn't working as expected

I have a Crew property, the property has several fields, few of which are Code and InvoiceAmount. The plus button is supposed to insert a new crew into an ObservableCollection of crews. Adding the first item works fine, however when the second item is inserted the first item's code changes to the second item and the second item has no visible code. How do I fix it so that a new crew is inserted every time I click the + button?

Starting UI:

enter image description here

After one item (a) has been added:

enter image description here

Second item (b) has been added:

enter image description here

Here's the ViewModel code:

public class MainPageViewModel : ViewModelBase
{
    public MainPageViewModel()
    {
        AddCrewCommand = new CustomCommand(param => addCrew(), null);
        Crews.CollectionChanged += new NotifyCollectionChangedEventHandler(Crews_Updated);
    }

    private void Crews_Updated(object sender, NotifyCollectionChangedEventArgs e)
    {
        RaisePropertyChanged("lvCrewList");
    }

    public Crew Crew { get; set; } = new Crew();

    public ObservableCollection<Crew> Crews { get; private set; } = new ObservableCollection<Crew>();

    public Crew SelectedCrew { get; set; }

    public ICommand AddCrewCommand { get; private set; }

    private void addCrew()
    {
        Crews.Add(Crew);
        Crew = new Crew();
    }

    public ObservableCollection<string> SelectedWorkOrder { get; set; }
}

ViewModelBase:

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Here's the XAML bit that assigns the Code field:

        <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
            <Label Content="Crew" Width="55" Height="25" Margin="10,10,0,0"/>
            <TextBox x:Name="txtCrew" Width="75" Height="25" Margin="0,10,10,0"
                Text="{Binding Crew.Code, Mode=TwoWay}" />
            <Button Content="+" Width="25" Height="25" Margin="0, 10, 0, 0" Command="{Binding AddCrewCommand}" />
        </StackPanel>

Crew Class:

public class Crew
{
    public string Code { get; set; }

    public decimal InvoiceAmount { get; set; } = 0;

    public Job Job { get; set; }

    public override string ToString() => Code;
}

Upvotes: 0

Views: 18

Answers (1)

Michal Ciechan
Michal Ciechan

Reputation: 13898

It is because you are not raising a PropertyChanged event for your Crew property, therefore the textbox is still bound to the previously added crew.

Change your MainPageViewModel.Crew property to the following:

public class MainPageViewModel : ViewModelBase
{
    .............
    private Crew _crew = new Crew();
    public Crew Crew
    {
        get { return _crew; }
        set
        {
            if (_crew == value) return;
            _crew = value;
            RaisePropertyChanged(nameof(Crew));
        }
    }
    .......
}

Upvotes: 1

Related Questions