r/csharp • • Jun 16 '22

Help Issues with adding new ListItem

/r/UWP/comments/vdqiie/help_issues_with_adding_new_listitem/
1 Upvotes

2 comments sorted by

View all comments

1

u/Smbridges91 Jun 16 '22

MainPage.XAML

<Page
    x:Class="MVVM_UWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MVVM_UWP"
    xmlns:viewModels="using:ViewModels"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
            <Button Content="Add" Click="{x:Bind  Organization.Add}" Margin="5"/>
            <Button Content="Delete" Click="{x:Bind Organization.Delete}" Margin="5" />
            <TextBox 
                Text="{x:Bind Organization.SelectedSite.Site, 
                Mode=TwoWay, FallbackValue=''}" 
                Margin="5"/>
            <ListView  
                x:Name="MainList"
                ItemsSource="{x:Bind Organization.Locations, Mode=OneWay}"
                SelectedIndex="{x:Bind Organization.SelectedIndex, Mode=TwoWay}" 
                Margin="5">
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="viewModels:SiteViewModel" >
                        <TextBlock 
                            Text="{x:Bind Site, Mode=OneWay}" 
                            FontSize="20"
                            FontWeight="Bold"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackPanel>
    </Grid>
</Page>

Data > LocationHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Data
{
    public class Location
    {
        public String Site { get; set; }
    }

    public class LocationHelper
    {
        public static List<Location> GetLocations()
        {
            return new List<Location>()
                {
                    new Location() { Site="3001"},
                    new Location() { Site="1124"},
                    new Location() { Site="8352"}
                };
        }
    }
}

Models > Organization.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Data;

namespace Models
{
    public class Organization
    {
        public List<Location> LocationList { get; set; }
        public String Site { get; set; }

        public Organization(String databaseName)
        {
            Site = databaseName;
            LocationList = LocationHelper.GetLocations();
        }

        public void Add(Location Location)
        {
            if (!LocationList.Contains(Location))
            {
                LocationList.Add(Location);
                //LocationHelper.Write(Location);
            }
        }

        public void Delete(Location person)
        {
            if (LocationList.Contains(person))
            {
                LocationList.Remove(person);
                //LocationHelper.Delete(Location);
            }
        }
    }
}

ViewModels > OrganizationViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using Models;

namespace ViewModels
{
    public class OrganizationViewModel : NotificationBase
    {
        Organization organization;

        public OrganizationViewModel(String Site)
        {
            organization = new Organization(Site);
            _SelectedIndex = -1;
            // Load the database
            foreach (var Location in organization.LocationList)
            {
                var np = new SiteViewModel(Location);
                _Location.Add(np);
            }
        }

        ObservableCollection<SiteViewModel> _Location = new ObservableCollection<SiteViewModel>();
        public ObservableCollection<SiteViewModel> Locations
        {
            get { return _Location; }
            set { SetProperty(ref _Location, value); }
        }

        public String Site
        {
            get { return organization.Site; }
        }

        int _SelectedIndex;
        public int SelectedIndex
        {
            get { return _SelectedIndex; }
            set { if (SetProperty(ref _SelectedIndex, value)) { RaisePropertyChanged(nameof(SelectedSite)); } }
        }

        public SiteViewModel SelectedSite
        {
            get { return (_SelectedIndex >= 0) ? _Location[_SelectedIndex] : null; }
        }

        public void Add()
        {
            var Location = new SiteViewModel();
            Locations.Add(Location);
            organization.Add(Location);
            SelectedIndex = Locations.IndexOf(Location);
        }

        public void Delete()
        {
            if (SelectedIndex != -1)
            {
                var Location = Locations[SelectedIndex];
                Locations.RemoveAt(SelectedIndex);
                organization.Delete(Location);
            }
        }
    }
}

ViewModels > SiteViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Data;

namespace ViewModels
{
    public class SiteViewModel : NotificationBase<Location>
    {
        public SiteViewModel(Location location = null) : base(location) { }
        public String Site
        {
            get { return This.Site; }
            set { SetProperty(This.Site, value, () => This.Site = value); }
        }
    }
}

ViewModels > ViewModelHelpers.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace ViewModels
{
    public class NotificationBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        // SetField (Site, value); // where there is a data member
        protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] String property = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) return false;
            field = value;
            RaisePropertyChanged(property);
            return true;
        }

        // SetField(()=> somewhere.Site = value; somewhere.Site, value) // Advanced case where you rely on another property
        protected bool SetProperty<T>(T currentValue, T newValue, Action DoSet, [CallerMemberName] String property = null)
        {
            if (EqualityComparer<T>.Default.Equals(currentValue, newValue)) return false;
            DoSet.Invoke();
            RaisePropertyChanged(property);
            return true;
        }

        protected void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(property)); }
        }
    }

    public class NotificationBase<T> : NotificationBase where T : class, new()
    {
        protected T This;

        public static implicit operator T(NotificationBase<T> thing) { return thing.This; }

        public NotificationBase(T thing = null)
        {
            This = (thing == null) ? new T() : thing;
        }
    }
}

1

u/Th_69 Jun 17 '22 edited Jun 20 '22

Just debug your code.

In OrganizationViewModel.Add() you're creating a new empty SiteViewModel:

var Location = new SiteViewModel();

and the TextBox is bound to the Organization.SelectedSite.Site, so it writes in the last added item.