I store in dictionary all the values of listView in dictionary-value and store its index in dictionary-keys at form load.
I am using dictionary as a medium of index storage for corresponding transferred listitems.
Now i transfer from a to b on a button click (a listview is full and b is empty) then i do again transfer the same element from b to a on another button click. It is now appended at last when i do back to b->a transfer. But i want it to append on same index on which it was before transferring to a->b.
I mean when i do b->a transfer then it must go to same index where it used to stay before
My code is this (please correct me where i am wrong and please give me a solution)
private void Form1_Load(object sender, EventArgs e)
{
//storing data in dictionary
}
private void button1_Click(object sender, EventArgs e)
{
MoveSelectedItems(listView1, listView2,0);
}
private void button2_Click(object sender, EventArgs e)
{
MoveSelectedItems(listView2, listView1,1);
}
private void MoveSelectedItems(ListView source, ListView target, int flag)
{
ListViewItem temp = source.SelectedItems[0];
source.Items.Remove(temp);
if(flag==0)//called when i do a->b
{
target.Items.Add(temp);
}
else
{
int index=getIndex(temp);
target.Items.Insert(index, temp);
}
}
private int getIndex(ListViewItem temp)
{
int index = 0;
if (dictList.ContainsValue(temp.Text))
{
foreach (KeyValuePair<int, string> pair in dictList)
if (temp.Text.Equals(pair.Value))
{
index=Convert.ToInt32(pair.Key);
return index;
}
}
return index;
}
What you actually need is, after taking the desired index from the dictionary, to search the items currently in the list view and find the actual insert position.
There are different way you can do that, here is one using binary search:
else
{
foreach (ListViewItem item in source.SelectedItems)
{
ListViewItem lvItem = item.Clone() as ListViewItem;
int index = dictList[item.Text];
// Insert at appropriate position based on index value
if (index == 0) // Always first
target.Items.Insert(0, lvItem);
else if (index == dictList.Count - 1) // Always last
target.Items.Add(lvItem);
else
{
// Binary search the current target items
int lo = 0, hi = target.Items.Count - 1;
while (lo <= hi)
{
int mid = lo + (hi - lo) / 2;
if (index < dictList[target.Items[mid].Text])
hi = mid - 1;
else
lo = mid + 1;
}
// Here lo variable contains the insert position
target.Items.Insert(lo, lvItem);
}
source.Items.Remove(item);
}
}
EDIT: Here is a [mcve] proving that it works:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Samples
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form();
var splitView = new SplitContainer { Dock = DockStyle.Fill, Parent = form, Orientation = Orientation.Vertical };
var listView1 = new ListView { Dock = DockStyle.Fill, Parent = splitView.Panel1, View = View.List };
var listView2 = new ListView { Dock = DockStyle.Fill, Parent = splitView.Panel2, View = View.List };
var buttonPanel = new Panel { Dock = DockStyle.Bottom, Parent = form };
var button1 = new Button { Parent = buttonPanel, Left = 16, Top = 8, Text = ">" };
var button2 = new Button { Parent = buttonPanel, Left = button1.Right + 16, Top = 8, Text = "<" };
buttonPanel.Height = button1.Height + 16;
var dictList = new Dictionary<string, int>
{
{ "first", 0 },
{ "second", 1 },
{ "third", 2 },
{ "fourth", 3 },
{ "fifth", 4 },
{ "sixth", 5 },
{ "seventh", 6 },
};
foreach (var item in dictList)
listView1.Items.Insert(item.Value, item.Key);
Action<ListView, ListView, int> MoveSelectedItems = (ListView source, ListView target, int flag) =>
{
while (source.SelectedItems.Count > 0)
{
var item = source.SelectedItems[0];
source.Items.Remove(item);
if (flag == 0)
{
target.Items.Add(item);
}
else
{
int index = dictList[item.Text];
// Insert at appropriate position based on index value
if (index == 0) // Always first
target.Items.Insert(0, item);
else if (index == dictList.Count - 1) // Always last
target.Items.Add(item);
else
{
// Binary search the current target items
int lo = 0, hi = target.Items.Count - 1;
while (lo <= hi)
{
int mid = lo + (hi - lo) / 2;
if (index < dictList[target.Items[mid].Text])
hi = mid - 1;
else
lo = mid + 1;
}
// Here lo variable contains the insert position
target.Items.Insert(lo, item);
}
}
}
};
button1.Click += (sender, e) => MoveSelectedItems(listView1, listView2, 0);
button2.Click += (sender, e) => MoveSelectedItems(listView2, listView1, 1);
Application.Run(form);
}
}
}
You can add a ListViewItemComparer to the list view. Like this.
public class ListViewItemComparer : IComparer
{
public int Compare(object x, object y)
{
return (((ListViewItem)x).Index > ((ListViewItem)y).Index ? 1 : -1);
}
}
And then in MoveSelectedItems:
this.listView1.ListViewItemSorter = new ListViewItemComparer();
Good luck.
Related
I have a class like this:
public class PricingRecord
{
private string _name;
private float[] _prices;
public PricingRecord(string name, float[] prices)
{
_name = name;
_prices = prices;
}
[DisplayName("Name")]
public string PricingName => _name;
public float[] Prices => _prices;
}
I want to map "Prices" to "Price 1", "Price 2", etc. columns in a DataGridView. I can get the columns to appear, but don't know how to make the mapping work.
Here's the main window:
public partial class MainForm : Form
{
private int _numPricingColumns;
private BindingList<PricingRecord> _records;
public MainForm()
{
InitializeComponent();
SetupPricingData();
SetupGridView();
}
private void SetupPricingData()
{
_records = new BindingList<PricingRecord>();
for (int i = 0; i < 100; i++)
{
var pricing = new PricingRecord($"Name {i + 1}", new [] { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f });
_records.Add(pricing);
}
_numPricingColumns = _records[0].Prices.Length;
GridView.DataSource = _records;
}
private void SetupGridView()
{
//GridView.AutoGenerateColumns = false;
//DataGridViewColumn column = new DataGridViewTextBoxColumn
//{
// Name = "Name",
// DataPropertyName = "PricingName"
//};
//GridView.Columns.Add(column);
for (int i = 0; i < _numPricingColumns; i++)
{
DataGridViewColumn column = new DataGridViewTextBoxColumn
{
Name = $"Price {i + 1}",
DataPropertyName = $"Price{i + 1}"
};
GridView.Columns.Add(column);
}
}
}
If I don't use BindingView I can set it up all by hand, but then I have to maintain the rows and columns myself. I'd like to use BindingView but this doesn't seem to support mapping many columns to an array.
I found I could get the pricing columns to be handled by drawing them. The use I needed was readonly so this is my solution for now:
private void OnCellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
for (int i = 0; i < _numPricingColumns; i++)
{
var name = $"Price {i + 1}";
var column = GridView.Columns[name];
if (column.Index == e.ColumnIndex && e.RowIndex >= 0)
{
var row = GridView.Rows[e.RowIndex];
var record = row.DataBoundItem as PricingRecord;
if (record != null)
{
var selected = (e.State & DataGridViewElementStates.Selected) != 0;
using (var brush = new SolidBrush(selected ? e.CellStyle.SelectionForeColor : e.CellStyle.ForeColor))
{
e.PaintBackground(e.ClipBounds, selected);
e.Graphics.DrawString(record.Prices[i].ToString("N"), e.CellStyle.Font, brush,
e.CellBounds.X + 2.0f, e.CellBounds.Y + 2.0f, StringFormat.GenericDefault);
e.Handled = true;
}
}
}
}
}
A faster and more flexible solution proved to be dropping BindingList and directly poking the cells in the grid. The need to map an array field to multiple columns becomes moot as it's done by hand.
in this program, when the Recall button (recallBtn_Click()) is clicked, it calls a method (that calculates directions) from another class which should then call the showPath() method. the show path method should then display its output in a textBox. But the values don't show even though i can see from debugging that the values are being sent to the text box. can anybody tell me where i went wrong?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
storeRetSelect.SelectedIndex = 0;
PrioritySelect.SelectedIndex = 0;
}
public void showPath(List<PathFinderNode> mPath)
{
var T = new Form1().directionsTextBox;
foreach (PathFinderNode node in mPath)
{
if ((node.X - node.PX) > 0) { T.Text += "Right" + System.Environment.NewLine ; }
if ((node.X - node.PX) < 0) { T.Text += "Left" + System.Environment.NewLine; }
if ((node.Y - node.PY) > 0) { T.Text += "UP" + System.Environment.NewLine; }
if ((node.Y - node.PY) < 0) { T.Text += "Down" + System.Environment.NewLine; }
}
}
private void recallBtn_Click(object sender, EventArgs e)
{
var path = new pathPlan();
string desigString = inputTextBox.Text;
int[] desig = new int[3];
for (int i = 0; i < desigString.Length; i++) { desig[i] = (int)char.GetNumericValue(desigString[i]); }
path.Recall(desig[1], desig[2], (-1) * desig[0]);
}
}
With this line you are initialising a new object and get the reference of the textbox there.
var T = new Form1().directionsTextBox;
But I assume you want to use the textbox of the form which is allready open. Change the line to the following to access the textbox of the current object.
var T = this.directionsTextBox;
I am currently having an issue with my code where the focus on a particular item row will not hold. I created the int focusReference to keep track of the currently focused row, but it appears to reset to 0 after every couple of seconds, i.e. once the user selects a row, in a couple of seconds, it "forgets" the users selection. I've included an example below:
As you can see from my code below, I have a timer doing something every few seconds. I've already been told that refreshing my list every few seconds is leading to the loss in focus every few seconds.
How would I programmatically set focus on an item, to retain that focus a user has? I've tried to implement a FocusItem method but it doesn't seem to be working. This is a very important aspect of my program, and I need it to work properly otherwise other features (like the right click context menu I am implementing), will also not work:
public MainWindow()
{
InitializeComponent();
int focusReference = 0;
PlotListView.SelectionChanged += (s, ee) => { PlotListView_SelectionChanged(s, ee, focusReference); };
var dbObject = new DbConnect();
dbObject.OpenConnection();
RefreshPlotTimer(filterReference, focusReference);
}
public void PlotListView_SelectionChanged(object sender, SelectionChangedEventArgs e, int focusReference)
{
if (PlotListView.SelectedItems.Count == 0) return;
var selectedItem = (DbConnect.PlotList)PlotListView.SelectedItems[0];
focusReference = Convert.ToInt32(selectedItem.PlotId);
FocusItem(focusReference);
}
private void FocusItem(int focusReference)
{
if (PlotListView.SelectedItems.Count != 0)
{
DbConnect.PlotList plotList =
PlotListView.Items.OfType<DbConnect.PlotList>()
.FirstOrDefault(p => Convert.ToInt32(p.PlotId) == focusReference);
if (plotList != null)
{
//get visual container
var container = PlotListView.ItemContainerGenerator.ContainerFromItem(plotList) as ListViewItem;
if (container != null)
{
container.IsSelected = true;
container.Focus();
}
}
}
}
public void RefreshPlotTimer(int filterReference, int focusReference)
{
var refreshTimer = new Timer();
refreshTimer.Elapsed += (sender, e) => RefreshPlot(sender, e, filterReference, focusReference);
refreshTimer.Interval = 2500;
refreshTimer.Enabled = true;
}
public void RefreshPlot(object source, ElapsedEventArgs e, int filterReference, int focusReference)
{
var dbObject = new DbConnect();
dbObject.OpenConnection();
dbObject.RefreshPlot();
Dispatcher.Invoke(() =>
{
FocusItem(focusReference);
if (!string.IsNullOrWhiteSpace(FilterTextBox.Text) &&
(!Regex.IsMatch(FilterTextBox.Text, "[^0-9]")))
{
filterReference = Convert.ToInt32(FilterTextBox.Text);
}
});
ResetPlot(filterReference);
}
public void ResetPlot(int filterReference)
{
var dbObject = new DbConnect();
dbObject.OpenConnection();
List<DbConnect.PlotList> plotList = dbObject.SelectPlotLists(filterReference);
Dispatcher.BeginInvoke(
new ThreadStart(() => PlotListView.ItemsSource = plotList));
int jobSum = 0;
int bidSum = 0;
foreach (DbConnect.PlotList item in PlotListView.Items)
{
jobSum += Convert.ToInt32(item.Jobs);
bidSum += Convert.ToInt32(item.Bids);
}
Dispatcher.BeginInvoke(
new ThreadStart(() => JobBidRatioTextBlock.Text = jobSum + " jobs - " + bidSum + " bids"));
}
UPDATE 2
I reverted back to the code I was using initially, could it be that the FocusItem method is not retaining the listview item focus?
private void FocusItem(int focusReference)
{
Dispatcher.Invoke(() =>
{
if (PlotListView.SelectedItems.Count != 0)
{
DbConnect.PlotList plotList =
PlotListView.Items.OfType<DbConnect.PlotList>()
.FirstOrDefault(p => Convert.ToInt32(p.PlotId) == focusReference);
if (plotList != null)
{
//get visual container
var container = PlotListView.ItemContainerGenerator.ContainerFromItem(plotList) as ListViewItem;
if (container != null)
{
container.IsSelected = true;
container.Focus();
}
}
}
}
}
I'm calling it at the right places and the index is definitely the right one, according to what is written in the console.
PlotListView_SelectionChanged 4
Before refresh 4
After refresh 4
PlotListView_SelectionChanged 7
Before refresh 7
After refresh 7
Before refresh 7
After refresh 7
Both in the refresh plot method...
public void RefreshPlot(object source, ElapsedEventArgs e)
{
var dbObject = new DbConnect();
dbObject.OpenConnection();
dbObject.RefreshPlot();
Console.WriteLine("\rBefore refresh " + focusReference);
Dispatcher.Invoke(() =>
{
if (!string.IsNullOrWhiteSpace(FilterTextBox.Text) &&
(!Regex.IsMatch(FilterTextBox.Text, "[^0-9]")))
{
filterReference = Convert.ToInt32(FilterTextBox.Text);
}
});
ResetPlot(filterReference);
Console.WriteLine("After refresh " + focusReference);
FocusItem(focusReference);
}
And the reset plot method...
public void ResetPlot(int filterReference)
{
// Establish MySQL connection
var dbObject = new DbConnect();
dbObject.OpenConnection();
// Fill plot list view
List<DbConnect.PlotList> plotList = dbObject.SelectPlotLists(filterReference);
Dispatcher.BeginInvoke(
new ThreadStart(() => PlotListView.ItemsSource = plotList));
int jobSum = 0;
int bidSum = 0;
foreach (DbConnect.PlotList item in PlotListView.Items)
{
jobSum += Convert.ToInt32(item.Jobs);
bidSum += Convert.ToInt32(item.Bids);
}
FocusItem(focusReference);
// Determine job/bid list ratio
Dispatcher.BeginInvoke(
new ThreadStart(() => JobBidRatioTextBlock.Text = jobSum + " jobs - " + bidSum + " bids"));
}
Before doing the refresh you need to remember the SelectedItem and set it agian after the refresh. That's the theory.
In case of objects you'll need to find which one is now the same as the one before (because it's not the same instance anymore) so you'll have to search for it in the new results list and assign it to the SelectedItem.
The easiest way would be to just re-set the SelectedIndex but because the list probably changes it would also sooner or later re-select the wrong item.
// Gets current selection.
public DbConnect.PlotList SelectedPlotList
{
get
{
return PlotListView.SelectedItem as DbConnect.PlotList;
}
}
public void ResetPlot(int filterReference)
{
// Get current plot number;
int? plotNumber = SelectedPlotList == null ? (int?)null : SelectedPlotList.PlotNumber;
var dbObject = new DbConnect();
dbObject.OpenConnection();
List<DbConnect.PlotList> plotList = dbObject.SelectPlotLists(filterReference);
// Find the plot list in the new list.
DbConnect.PlotList selectPlotList =
plotNumber.HasValue
? plotList.Where(x => x.PlotNumber == plotNumber.Value).FirstOrDefault();
: null;
Dispatcher.BeginInvoke(new ThreadStart(() => PlotListView.ItemsSource = plotList));
// Re-select plot list if found in the new list.
if (selectPlotList != null)
{
PlotListView.SelectedItem = selectPlotList;
}
int jobSum = 0;
int bidSum = 0;
foreach (DbConnect.PlotList item in PlotListView.Items)
{
jobSum += Convert.ToInt32(item.Jobs);
bidSum += Convert.ToInt32(item.Bids);
}
Dispatcher.BeginInvoke(
new ThreadStart(() => JobBidRatioTextBlock.Text = jobSum + " jobs - " + bidSum + " bids"));
}
EDIT:
I've just tested a quick & dirty demo and it works. There must be a bug somewhere else.
This generates 7 items with unique ids and re-selects the last selected item if it is drawn again:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
List<ListViewItem> items = new List<ListViewItem>();
Random rnd = new Random(DateTime.Now.Millisecond);
HashSet<int> ids = new HashSet<int>();
for (int i = 0; i < 7; i++)
{
int id = 0;
do
{
id = rnd.Next(0, 10);
} while (ids.Contains(id));
ids.Add(id);
items.Add(new ListViewItem() { Id = id, Name = "Item-" + i });
}
int? selectedId = listView1.SelectedItem != null ? (listView1.SelectedItem as ListViewItem).Id : (int?)null;
listView1.ItemsSource = items;
if (selectedId.HasValue)
{
listView1.SelectedItem = items.Where(x => x.Id == selectedId).FirstOrDefault();
listView1.Focus();
}
}
}
class ListViewItem
{
public int Id { get; set; }
public string Name { get; set; }
}
I have two classes that get all the minimized windows:
The first class is WindowSnap.cs:
WindowSnap.cs
The second class is WindowSnapCollection.cs:
WindowSnapCollection.cs
In the first class in the windowSnap there is a method called GetAllWindows:
public static WindowSnapCollection GetAllWindows(bool minimized, bool specialCapturring)
{
windowSnaps = new WindowSnapCollection();
countMinimizedWindows = minimized;//set minimized flag capture
useSpecialCapturing = specialCapturring;//set specialcapturing flag
EnumWindowsCallbackHandler callback = new EnumWindowsCallbackHandler(EnumWindowsCallback);
EnumWindows(callback, IntPtr.Zero);
return new WindowSnapCollection(windowSnaps.ToArray(), true);
}
In the end i used a breakpoint on the return line and windowSnaps variable contain 15 items.
For example the first item is:
[0] = {Window Text: , Handle: 31918532}
The second one is:
[3] = {Window Text: ?How can i get from a window only the text without the Handle number ? - Stack Overflow - Google Chrome?, Handle: 64424060}
In the first item i was able to do on my own to remove this item since it's text is only "," and this window show nothing.
But number [3] and other items i want first to remove from them the part Handle: 64424060
I don't need that the user will see this information. But only the text so for example number [3] should look like:
?How can i get from a window only the text without the Handle number ? - Stack Overflow - Google Chrome?
And to fix those "?" that are in the beginning of the line.
But the idea is to display only the name of each window and not the whole text with the handle number.
This is how i add the items(windows) to form1 listBox:
this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray());
In the listBox i want to see the items names or description/titles not the whole text with the handle number.
You can do a little trick. It is not nice but works. Add a new listbox eg listBox1 with the same size on top of listBoxSnap.
add in public Form1():
public Form1()
{
...
for (int i = listBoxSnap.Items.Count - 1; i >= 0; i--)
{
string tt = listBoxSnap.Items[i].ToString();
if (tt.Contains(" ,"))
{
listBoxSnap.Items.RemoveAt(i);
}
}
buttonSnap.Enabled = true;
//add here ->
string[] myList = new string[listBoxSnap.Items.Count];
for (int i = 0; i < listBoxSnap.Items.Count; i++)
{
string tt = listBoxSnap.Items[i].ToString();
int index = tt.LastIndexOf(",");
myList [i] = tt.Substring(0, index);
}
listBox1.Items.AddRange(myList);
rectangles = new Rectangle[listBoxSnap.Items.Count];
isCropped = new bool[listBoxSnap.Items.Count];
if (this.listBoxSnap.Items.Count > 0)
{
this.listBoxSnap.SetSelected(0, true);
this.listBox1.SetSelected(0, true);
}
listBoxSnap.Select();
listBox1.Select();
}
change private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e) to:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBoxSnap.SelectedIndex = listBox1.SelectedIndex;
drawpicbox(this.listBoxSnap.SelectedIndex);
}
and delete this.listBoxSnap.SelectedIndexChanged += new System.EventHandler(this.listBoxSnap_SelectedIndexChanged); from Form1.Designer.cs
Add this event:
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var item = listBox1.IndexFromPoint(e.Location);
if (item >= 0)
{
listBox1.SelectedIndex = item;
listBoxSnap.SelectedIndex = listBox1.SelectedIndex;
cm.Show(listBox1, e.Location);
}
}
}
And lastly add in private void RefreshWindowsList()
private void RefreshWindowsList()
{
...
for (int i = listBoxSnap.Items.Count - 1; i >= 0; i--)
{
string tt = listBoxSnap.Items[i].ToString();
if (tt.Contains(" ,"))
{
listBoxSnap.Items.RemoveAt(i);
}
}
//add here ->
string[] myList = new string[listBoxSnap.Items.Count];
for (int i = 0; i < listBoxSnap.Items.Count; i++)
{
string tt = listBoxSnap.Items[i].ToString();
int index = tt.LastIndexOf(",");
myList [i] = tt.Substring(0, index);
}
listBox1.Items.Clear();
listBox1.Items.AddRange(myList);
rectangles = new Rectangle[listBoxSnap.Items.Count];
isCropped = new bool[listBoxSnap.Items.Count];
textBoxIndex.Text = listBoxSnap.Items.Count.ToString();
if (this.listBoxSnap.Items.Count > 0)
{
this.listBoxSnap.SetSelected(0, true);
this.listBox1.SetSelected(0, true);
}
listBoxSnap.Select();
listBox1.Select();
}
Valter
Just learning C# (along with object and event programing) and the teacher didn't really show us how to get things done.
class Postion
{
private int[] x_coordinate = new int[100];
private int[] y_coordinate = new int[100];
private double[] speed = new double[100];
private int[] direction = new int[100];
const int MAX_SPEED = 50;
int counter = 0;
public Postion()
{
x_coordinate[counter] = 0;
y_coordinate[counter] = 0;
speed[counter] = 0;
direction[counter] = 0;
}
//get set methods
public int X
{
get
{
return x_coordinate[counter];
}
set
{
x_coordinate[counter] = value;
}
}
There is one more Class between them
The values are frist assigned by a button click.
Airplane newplane = new Airplane();
private void BtnCreate_Click(object sender, EventArgs e)
{
bool box = txtName.Text != "";
if (box == true)
newplane.Name = txtName.Text;
else { }
box = txtx.Text != "";
if (box == true)
newplane.PlanePostion.X = int.Parse(txtx.Text);
else { }
Etc.
I can call on the array values for display for the list box.
private void lsbplanes_SelectedIndexChanged(object sender, EventArgs e)
{
placeholder = newplane.PlanePostion.Counter;
newplane.PlanePostion.Counter = lsbplanes.SelectedIndex;
if (newplane.PlanePostion.Counter < 0)
newplane.PlanePostion.Counter = 0;
else { }
lblxshow.Text = Convert.ToString(newplane.Getx());
but when using a destroy button to remove an item in the list box I need to have it so the box updates with the new values when the user selects the item in the listbox.
This is what I have to try and do it so far, it sets all the ones above to 0s but does remove the the deleted one fine
private void BtnKill_Click(object sender, EventArgs e)
{
if (lsbplanes.SelectedIndex == -1)
{
MessageBox.Show("Please select an item first.", "No item selected", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
placeholder = lsbplanes.SelectedIndex;
newplane.PlanePostion.Counter = lsbplanes.Items.Count;
while (newplane.PlanePostion.Counter > placeholder)
{
placex = newplane.PlanePostion.X;
placey = newplane.PlanePostion.Y;
placespeed = newplane.Getspeed();
placedic = newplane.Getdirection();
newplane.PlanePostion.Counter--;
newplane.PlanePostion.X = placex;
newplane.PlanePostion.Y = placey;
newplane.PlanePostion.Speed = placespeed;
newplane.PlanePostion.Direction = placedic;
}
lsbplanes.Items.RemoveAt(lsbplanes.SelectedIndex);
newplane.PlanePostion.Counter = lsbplanes.Items.Count;
}
anyone can help me on this?
I was torn in this question, answer exactly what your problem is, or suggest that you redesign it.
#Marc is right you should be using some sort of List<Position> on your Plane object (or a ReadOnlyObservableCollection<Position>).
#Marc is also right, that the problem you are having is that you are trying to push the values down from the end of the list and overwriting them. In these cases it is better to start from the deletion point and pull them down.
So if you have {1,2,3,4,5,6,7,8,9,10} and you delete from item 5, you would have {1,2,3,4,10,10,10,10,10,10}. The code below will let you end up with {1,2,3,4,6,7,8,9,0}
placeholder = lsbplanes.SelectedIndex;
int idx = placeholder;
while (idx < lsbplanes.Items.Count)
{
newplane.PlanePosition.Counter = idx+1;
placex = newplane.PlanePostion.X;
placey = newplane.PlanePostion.Y;
placespeed = newplane.Getspeed();
placedic = newplane.Getdirection();
newplane.PlanePostion.Counter = idx;
newplane.PlanePostion.X = placex;
newplane.PlanePostion.Y = placey;
newplane.PlanePostion.Speed = placespeed;
newplane.PlanePostion.Direction = placedic;
idx++;
}
// Need to zero out elements at the end
newplant.PlanePosition.Counter = lsbplanes.Items.Count;
/* Zeroing code goes here */
newplane.PlanePosition.Counter = placeholder;
lsbplanes.Items.RemoveAt(lsbplanes.SelectedIndex);