Проблема добавления строки в комбинированный список данных c# - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь создать сетку данных, в которой в качестве первой ячейки используется поле со списком. У меня странное поведение при добавлении строки в: - Если я выбираю элемент в поле со списком и перехожу к следующей ячейке, выбор поля со списком очищается. Это происходит только в том случае, если в этой строке ранее ничего не заполнялось - ObervableCollection, хранящий данные из сетки данных, не обновляется.

Я, должно быть, что-то не так с привязками, но не могу разобраться что ...

Вот код ( на основе этого урока )

GridDataModel

namespace InteractiveGraph.Grid
{
public class DoliInput : ObservableObject, ISequencedObject
{

    private double _speed;
    private string _CTRL;
    private double _destination;
    private double _duration;
    private int _seqNb;



    public string CTRL
    {
        get => _CTRL;
        set
        {
            _CTRL = value;
            OnPropertyChanged("CTRL");
        }
    }
    public double Destination
    {
        get => _destination;
        set
        { 
            _destination = value; 
            OnPropertyChanged("Destination"); 
        }
    }
    public double Speed 
    { 
        get => _speed; 
        set 
        { 
            _speed = value; 
            OnPropertyChanged("Speed"); 
        } 
    }
    public double Duration 
    { 
        get => _duration; 
        set 
        { 
            _duration = value; 
            OnPropertyChanged("Duration"); 
        } 
    }

    public int SequenceNumber 
    { 
        get => _seqNb;
        set
        {
            _seqNb = value;
            OnPropertyChanged("SequenceNumber");
        }
    }

    //THIS EMPETY CONSTRUCTOR IS REALLY IMPORTANT. IT ALLOWS THE DISPLAY OF THE EMPTY ROW AT THE END OF THE DATAGRID 
    public DoliInput(){  }

    public DoliInput(string CTRL, double destination, double speed, double duration)
    {
        this._CTRL = CTRL;
        this._destination = destination;
        this._speed = speed;
        this._duration = duration;
    }
}

GridDataVM

namespace InteractiveGraph.Grid
{
public class DataGridVM : ViewModelBase
{

    void OnDoliCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // Update item count
        this.ItemCount = this.DoliInputCollection.Count;

        // Resequence list
        SetCollectionSequence(this.DoliInputCollection);
    }


    private ObservableCollection<DoliInput> _doliInputCollection;
    private int _itemCount;


    public DataGridVM()
    {
        this.Initialise();
    }


    public ObservableCollection<DoliInput> DoliInputCollection
    { 
        get => _doliInputCollection;
        set
        {
            _doliInputCollection = value;
            OnPropertyChanged("DoliInputCollection");
        }
    }

    public int ItemCount 
    { 
        get => _itemCount;
        set 
        { 
            _itemCount = value;
            OnPropertyChanged("ItemCount");
        }
    }
    /// <summary>
    /// Return selected item in the grid
    /// </summary>
    public DoliInput SelectedItem { get; set; }

    /// <summary>
    /// Resets the sequential order of a collection.
    /// </summary>
    /// <param name="targetCollection">The collection to be re-indexed.</param>
    public static ObservableCollection<T> SetCollectionSequence<T>(ObservableCollection<T> targetCollection) where T : ISequencedObject
    {
        // Initialize
        var sequenceNumber = 1;

        // Resequence
        foreach (ISequencedObject sequencedObject in targetCollection)
        {
            sequencedObject.SequenceNumber = sequenceNumber;
            sequenceNumber++;
        }

        // Set return value
        return targetCollection;
    }

    private void Initialise()
    {
        //Create inputList
        _doliInputCollection = new ObservableCollection<DoliInput>();

        //Add items
        _doliInputCollection.Add(new DoliInput("Load", 3, 2, 1));
        _doliInputCollection.Add(new DoliInput("Position", 3, 11, 1));
        _doliInputCollection.Add(new DoliInput("Position", 3, 2, 4));
        _doliInputCollection.Add(new DoliInput("Load", 3, 2, 1));

        //Subscribe to the event that gets trigger when change occurs
        _doliInputCollection.CollectionChanged += OnDoliCollectionChanged;

        //Start indexing items
        this.DoliInputCollection = SetCollectionSequence(this.DoliInputCollection);

        //Update if changes
        this.OnPropertyChanged("DoliInputCollection");
        this.OnPropertyChanged("GridParam");
    }
}
}

Файл xaml

<Window x:Class="InteractiveGraph.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:InteractiveGraph"
    xmlns:dataGrid="clr-namespace:InteractiveGraph.Grid"
    xmlns:vc="clr-namespace:InteractiveGraph.BugFix"
    mc:Ignorable="d"
    Title="MainWindow" Height="502.869" Width="935.246" SizeChanged="Window_SizeChanged">
<Window.DataContext>
    <dataGrid:DataGridVM />
</Window.DataContext>
<Grid Background="LightGreen">
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="3*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid>
        <DataGrid   Grid.Row="0" Grid.Column="0" 
                    HorizontalAlignment="Center" Height="100" Margin="0" 
                    VerticalAlignment="Center" Width="522" 
                    ItemsSource="{Binding DoliInputCollection}" AllowDrop="True" SelectionMode="Extended"
                    SelectedItem="{Binding SelectedItem}"
                    AutoGenerateColumns="False" ColumnWidth="*"
                    Name="inputlist" 
                    CanUserSortColumns="False"
                    CanUserAddRows="True"
                    DataContextChanged="OnMainGridDataContextChanged" 
                    RowEditEnding="inputlist_RowEditEnding">

            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Ctrl type">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding CbItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                                      SelectedValue="{Binding CTRL, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Binding="{Binding Destination, Mode=TwoWay}" Header="Destination" />
                <DataGridTextColumn Binding="{Binding Speed, Mode=TwoWay}" Header="Speed" />
                <DataGridTextColumn Binding="{Binding Duration, Mode=TwoWay}" Header="Duration(s)" >
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Grid>
</Window>

Код (он должен быть пустым, я знаю .. ..)

 public partial class MainWindow : Window
{

    public List<string> CbItem { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        CbItem = new List<string> { "Position", "Load" };
    }

    //To be removed, trying to understand what is going wrong
    private void inputlist_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        Console.WriteLine("######COUNT " + _viewModel.DoliInputCollection.Count().ToString());
        foreach (var item in _viewModel.DoliInputCollection)
        {
            Console.WriteLine("CTRL = " + item.CTRL + ", destination = " + item.Destination.ToString() + ", SeqNum = " + item.SequenceNumber.ToString());
        }
    }
}

namespace InteractiveGraph.Utility
{
public abstract class ViewModelBase : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    #region Protected Methods

    /// <summary>
    /// Fires the PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The name of the changed property.</param>
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            PropertyChanged(this, e);
        }
    }

    #endregion
}
}

ISequenceObject

namespace InteractiveGraph.Utility
{
    /// <summary>
    /// An object that can be given a sequential order in a collection.
    /// </summary>
    public interface ISequencedObject
    {
        /// <summary>
        /// The sequence number of the object
        /// </summary>
        int SequenceNumber { get; set; }

    }
}

ObservaleObject

namespace InteractiveGraph.Utility
{ 
    public class ObservableObject : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Protected Methods

        /// <summary>
        /// Raises the PropertyChanged event.
        /// </summary>
        /// <param name="propertyName">The name of the property that was changed.</param>
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                PropertyChanged(this, e);
            }
        }

        #endregion
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...