Databinding problem in dropdownlist box by generics in C# - c#

I want to implement stack in my program by Genericx. I have a textbox and button to add elements in stack, a dropdownlist box and a button to bind total stack in dropdownlist box.
I have generic class and the code is below:
[Serializable]
public class myGenClass<T>
{
private T[] _elements;
private int _pointer;
public myGenClass(int size)
{
_elements = new T[size];
_pointer = 0;
}
public void Push(T item)
{
if (_pointer > _elements.Length - 1)
{
throw new Exception("Stack is full");
}
_elements[_pointer] = item;
_pointer++;
}
public T Pop()
{
_pointer--;
if (_pointer < 0)
{
throw new Exception("Stack is empty");
}
return _elements[_pointer];
}
public T[] myBind()
{
T[] showall = new T[_pointer];
Array.Copy(_elements,showall, _pointer);
T[] newarray = showall;
Array.Reverse(showall);
return showall;
}
}
and my .cs page is below:
public partial class _Default : System.Web.UI.Page
{
myGenClass<int> mystack = new myGenClass<int>(25);
protected void Button1_Click(object sender, EventArgs e)
{
mystack.Push(Int32.Parse(TextBox1.Text));
//DropDownList1.Items.Add(mystack.Pop().ToString());
TextBox1.Text = string.Empty;
TextBox1.Focus();
}
protected void Button2_Click(object sender, EventArgs e)
{
//string[] db;
//db = Array.ConvertAll<int, string>(mystack.myBind(), Convert.ToString);
DropDownList1.DataSource = mystack.myBind();
DropDownList1.DataBind();
}
}
but when I bind the datasource property of dropdownlist box to generic type return array (i.e. myBind()), it shows empty... Please help..

I haven't looked at the myGenClass type, but are you persisting the instance of myGenClass between requests? Each button click would post to a new instance of the _default class which initializes with an empty stack. If the stack isn't persisted between requests, it will contain its default values.

Related

Differentiate items loading to list vs scroll event Xamarin forms listview

This is my code that can successfully detect scroll up or down:
MyListView.ItemAppearing += async (object sender, ItemVisibilityEventArgs e) =>
{
var currentIdx = CurrentList.IndexOf((MyClass)e.Item);
if (currentIdx > _lastItemAppearedIdx)
ShowChopped();
else
ShowFull();
_lastItemAppearedIdx = CurrentList.IndexOf((MyClass)e.Item);
};
What is working is the following: Items get added to the list, then once i start scrolling it works fine where ShowChoppedand ShowFull are methods with animations that just makes a simple animation to either half the size of an object or make it full. This works fine, but if i however click a new category that changes the content in the list, ItemAppearing gets triggered of course and ShowChoppedand ShowFull are called even though i only want it called during a scrollevent.
How would i be able to differentiate a scroll to a item collection change? I have only tried this on iOS.
Updated code:
public class ListView_iOS : ListViewRenderer
{
private IDisposable _offsetObserver;
private double _prevYOffset;
private IListView _myListView;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);
if (e.NewElement is IListView)
_offsetObserver = Control.AddObserver("contentOffset",
Foundation.NSKeyValueObservingOptions.New, HandleAction);
}
private static bool CloseTo(double x, double y)
{
return Math.Abs(x - y) < 0.1;
}
private void HandleAction(Foundation.NSObservedChange obj)
{
var effectiveY = Math.Max(Control.ContentOffset.Y, 0);
if (!CloseTo(effectiveY, _prevYOffset) && Element is IListView)
{
var myList = Element as IListView;
myList.IsScrolling = true;
}
}
}
You can differentiate items loading from list scrolling by
1 adding the code if (EmployeeView.IsScrolling) within ItemAppearing method.
2 adding the code EmployeeView.IsScrolling = false; within any function you write to change the appearing of items without scrolling action, for example, when you add items or change category.
And the EmployeeView.IsScrolling value is set from listview renderer.
So the code is like:
NativeListView.cs
public class NativeListView : ListView
{
public static readonly BindableProperty
IsScrollingProperty =
BindableProperty.Create(nameof(IsScrolling),
typeof(bool), typeof(NativeListView), false);
public bool IsScrolling
{
get { return (bool)GetValue(IsScrollingProperty); }
set { SetValue(IsScrollingProperty, value); }
}
}
NativeAndroidListViewRenderer.cs
[assembly: ExportRenderer(typeof(NativeListView), typeof(NativeAndroidListViewRenderer))]
namespace App2.Droid
{
public class NativeAndroidListViewRenderer : ListViewRenderer
{
public NativeAndroidListViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);
if (e.NewElement is NativeListView)
Control.Scroll += Control_Scroll;
}
private void Control_Scroll(object sender, AbsListView.ScrollEventArgs e)
{
var myList = Element as NativeListView;
myList.IsScrolling = true;
}
}
}
NativeiOSListViewRenderer.cs
private IDisposable _offsetObserver;
private double _prevYOffset;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);
if (e.NewElement is NativeListView)
_offsetObserver = Control.AddObserver("contentOffset",
Foundation.NSKeyValueObservingOptions.New, HandleAction);
}
private void HandleAction(Foundation.NSObservedChange obj)
{
var effectiveY = Math.Max(Control.ContentOffset.Y, 0);
if (!CloseTo(effectiveY, _prevYOffset) && Element is NativeListView)
{
var myList = Element as NativeListView;
myList.IsScrolling = true;
_prevYOffset = effectiveY;
}
}
private static bool CloseTo(double x, double y)
{
return Math.Abs(x - y) < 0.1;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing && _offsetObserver != null)
{
_offsetObserver.Dispose();
_offsetObserver = null;
}
}
MainPage.xaml.cs
namespace App2
{
public partial class MainPage : ContentPage
{
ObservableCollection<String> employeeList = new ObservableCollection<String>();
int count = 0;
public MainPage()
{
InitializeComponent();
AddButtion.Clicked += AddButtion_Clicked;
DelButtion.Clicked += DelButtion_Clicked;
EmployeeView.ItemsSource = employeeList;
EmployeeView.ItemAppearing += async (object sender, ItemVisibilityEventArgs e) =>
{
if (EmployeeView.IsScrolling) {
await DisplayAlert("ItemAppearing", e.Item + " row is appearing", "OK");
Console.WriteLine("ItemAppearing!!!!!!!!!!");
}
};
}
private void AddButtion_Clicked(object sender, EventArgs e)
{
employeeList.Add("Mr. Mono"+ count++);
EmployeeView.IsScrolling = false;
}
private void DelButtion_Clicked(object sender, EventArgs e)
{
if (employeeList.Count > 0) {
employeeList.RemoveAt(0);
}
EmployeeView.IsScrolling = false;
}
}
}

Dynamic created event in c#

I have a dynamical create button object where I want it to send an event to the mainform when I click on a button inside this object.
I have the code like this :
class Class1
{
internal class FObj_BtnRow
{
private Button[] _Btnmembers;
internal event EventHandler<SelValue_EArgs>[] e_BtnMember; //subscribe to a change
internal class SelValue_EArgs : EventArgs//events args (selected value)
{//return arguments in events
internal SelValue_EArgs(Boolean ivalue) { refreshed = ivalue; }//ctor
internal Boolean refreshed { get; set; }//accessors
}
private Boolean[] _ActONOFFValue; //Pump=0, valveInput = 1, Shower = 3, Washtool = 4 , WashWPcs = 5
private Boolean ActONOFFValue(int number)
{
_ActONOFFValue[number] = !_ActONOFFValue[number];
{
if (e_BtnMember[number] != null && number == 0) e_BtnMember[number](this, new SelValue_EArgs(_ActONOFFValue[number]));
}
return _ActONOFFValue[number];
}
public FObj_BtnRow(String[] TxtBtn, String UnitName)//ctor
{
_Btnmembers = new Button[TxtBtn.Length];
e_BtnMember = new EventHandler<SelValue_EArgs>[TxtBtn.Length];
for (int i = 0; i < TxtBtn.Length / 2; i++)
{
_Btnmembers[i].Click += new EventHandler(_Btnmembers_Click);
}
}
protected virtual void _Btnmembers_Click(object sender, EventArgs e)
{
int index = Array.IndexOf(_Btnmembers, (Button)sender);
ActONOFFValue(index);
}
}
}
But in the line : internal event EventHandler[] e_BtnMember;
the compiler told me that I should use a delegate. I don't understand good this remark, could you help me?
At the end the mainform should only subscribe to the event button click it wants.
And then in main we could use it to now when a button in the object multibutton row is clicked... like this:
public void main()
{
String[] txtbtn = new String[] { "btn1", "btn2", "btn3" };
FObj_BtnRow thisbtnrow = new FObj_BtnRow(txtbtn);
thisbtnrow.e_BtnMember[0] += new EventHandler<FObj_BtnRow.SelValue_EArgs> (btnmember0haschanged);
}
public void btnmember0haschanged(object sender, FObj_BtnRow.SelValue_EArgs newvalue)
{
bool thisnewvalue = newvalue.refreshed;
}
Can you help me?
Thanks in advance!!
I solved the problem by myself, thanks for your advices.
Code
class Class1
{
internal class FObj_BtnRowtest
{
private Button[] _Btnmembers;
public delegate void del_Btnmember(Boolean value);
public del_Btnmember[] btnvaluechanged;
internal class SelValue_EArgs : EventArgs//events args (selected value)
{//return boolean arguments in events
internal SelValue_EArgs(Boolean ivalue) { refreshed = ivalue; }//ctor
internal Boolean refreshed { get; set; }//accessors
}
private Boolean[] _ActONOFFValue;
private Boolean ActONOFFValue(int number)
{
_ActONOFFValue[number] = !_ActONOFFValue[number];
return _ActONOFFValue[number];
}
public FObj_BtnRowtest(int numofbtn, String UnitName)//ctor
{
_Btnmembers = new Button[numofbtn];
btnvaluechanged = new del_Btnmember[numofbtn];
_ActONOFFValue = new bool[numofbtn];
for (int i = 0; i < numofbtn / 2; i++)
{
_Btnmembers[i].Click += new EventHandler(_Btnmembers_Click);
}
}
protected virtual void _Btnmembers_Click(object sender, EventArgs e)
{
int index = Array.IndexOf(_Btnmembers, (Button)sender);
if (btnvaluechanged[index] != null) btnvaluechanged[index](ActONOFFValue(index));
}
}
}
And then in main
thisrow = new Class1.FObj_BtnRowtest(4,"thisunittest");//4 buttons
thisrow.btnvaluechanged[0] += new Class1.FObj_BtnRowtest.del_Btnmember(valuetesthaschanged);//to subscribe to btn0 change
using delegates make it easier. and yes we do need those kinds of stuffs to make code clearer and faster to developp.
Thanks all!!

C# windows Form help listing results from string array on to MessaeBox or new Form

enter image description here
Ok i need little help with this project. This is my main windows in widows Form
and this is code from MainForm:
using System;
using System.Windows.Forms;
namespace TestNiCat1
{
public partial class Form1 : Form
{
private Atleticar atleticar;
public Atleticar noviAtleticar { get { return atleticar; } }
public string tipDiscipline;
private string imeDiscipline { get; set; }
private int brojUcesnika { get; set; }
public string [] nizUcesnika { get; set; }
public string[] getskakac()
{
string[] arr = new string[listBox1.Items.Count];
for (int i = 0; i < listBox1.Items.Count; i++)
{
arr[i] = listBox1.Items[i].ToString();
}
return arr;
}
//listBox2.trkac to array
public string[] getTrkac()
{
string[] arr1 = new string[listBox2.Items.Count];
for (int i = 0; i < listBox1.Items.Count; i++)
{
arr1[i] = listBox2.Items[i].ToString();
}
return arr1;
}
public Form1()
{
InitializeComponent();
}
private void buttonDodaj_Click(object sender, EventArgs e)
{
if (radioButtonSkok.Checked)
{
atleticar = new Skakac(textBoxIme.Text,textBoxPrezime.Text,float.Parse(textBoxRezultat.Text));
this.listBox1.Items.Add(atleticar);
}
else if (radioButtonPrepone.Checked)
{
atleticar = new Trkac(textBoxIme.Text, textBoxPrezime.Text, float.Parse(textBoxRezultat.Text));
this.listBox2.Items.Add(atleticar);
}
}
private void buttonTrazi_Click(object sender, EventArgs e)
{
if (radioButtonSkok.Checked)
{
getskakac();
}
else if (radioButtonPrepone.Checked)
{
getTrkac();
}
}
}
}
i have 1 abstract class and 2 classes code :
namespace TestNiCat1
{
public abstract class Atleticar
{
protected string ime { get; set; }
protected string prezime { get; set; }
protected float rezultat { get; set; }
public override string ToString()
{
return ime + " " + prezime + " " + rezultat;
} }//abstract Atleticar
public class Skakac : Atleticar
{
private String tip;
public Skakac(String ime,String prezime,float rezultat)
{
this.rezultat = rezultat;
this.ime = ime;
this.prezime = prezime;
}
}public class Trkac : Atleticar
{
public Trkac(String ime,String prezime,float rezultat)
{
this.rezultat = rezultat;
this.ime = ime;
this.prezime = prezime;
}
}
}
what i need is to List all items when pressed Trazi button that will be stored into Listbox1 or listbox2 and sort them by highest result stored.
I made when i press trazi button to store all listbox items into String Array but i need help hot to sort them by highest score and show them into new messageBox OR if there is a way to sort items in listBox immidiatly as they been made in listbox by highest number.
I think this is what you look for
public string[] getskakac()
{
listBox1.Sorted = true;
return listBox1.Items.Cast<string>().ToArray();
}
It appears you may be better off having your abstract class Atleticar implement an IComparable interface. This will make sorting much easier and give you complete control over how Atleticar objects are sorted.
First you need to indicate that the Atleticar class will implement a CompareTo method for sorting:
public abstract class Atleticar : IComparable
Below is the CompareTo method needed when you implement the IComparable interface. I simply compare each object based on the rezultat variable but you can customize this to sort on another variable(s) if needed.
public int CompareTo(object obj) {
Atleticar other = (Atleticar)obj;
if (this.rezultat == other.rezultat)
return 0;
if (this.rezultat > other.rezultat)
return 1;
else
return -1;
}
Below I created a form with a ListBox and two buttons. One button fills the list box with some unsorted Atleticar objects. Button two sorts the list. I do not think you can directly sort the listbox1.Items so I created a list of Atleticar objects from the list box items and then sorted it, cleared the list box items then update it with the sorted data.
private List<Atleticar> GetData() {
List<Atleticar> list = new List<Atleticar>();
Atleticar atl = new Trkac("textBoxIme.Text1", "textBoxPrezime.Text1", 12);
list.Add(atl);
atl = new Trkac("textBoxIme.Text2", "textBoxPrezime.Text2", 1);
list.Add(atl);
atl = new Trkac("textBoxIme.Text3", "textBoxPrezime.Text3", 122);
list.Add(atl);
atl = new Trkac("textBoxIme.Text4", "textBoxPrezime.Text4", 99);
list.Add(atl);
atl = new Trkac("textBoxIme.Text5", "textBoxPrezime.Text5", 03);
list.Add(atl);
atl = new Trkac("textBoxIme.Text6", "textBoxPrezime.Text6", 67);
list.Add(atl);
atl = new Trkac("textBoxIme.Text7", "textBoxPrezime.Text7", -12);
list.Add(atl);
return list;
}
private void buttonGetData_Click(object sender, EventArgs e) {
listBox1.Items.Clear();
foreach (Atleticar a in GetData()) {
listBox1.Items.Add(a);
}
}
private void buttonSort_Click(object sender, EventArgs e) {
List<Atleticar> list = new List<Atleticar>();
foreach (Atleticar a in listBox1.Items) {
list.Add(a);
}
list.Sort();
listBox1.Items.Clear();
foreach (Atleticar a in list) {
listBox1.Items.Add(a);
}
}
Hope this makes sense.

Keeping a DataGridView autosorted

I've got a DataGridView that is backed by a SortableBindingList as described by this article.
This is essentially a BindingList whose Data source is a list of custom objects. The underlying custom objects are updated programatically.
My SortableBindingList allows me to sort each column in Ascending or Descending order. I've done this by overloading the ApplySortCore method
protected override void ApplySortCore(PropertyDescriptor prop,
ListSortDirection direction)
This works well for sorting when the column header is clicked on but won't sort automatically when cell in that column is programatically updated.
Has anyone else come up with a good solution for keeping a DataGridView sorted from programmatic updates of its underlying data source?
Try to override OnDataSourceChanged Event
public class MyGrid : DataGridView {
protected override void OnDataSourceChanged(EventArgs e)
{
base.OnDataSourceChanged(e);
MyComparer YourComparer = null;
this.Sort(YourComparer);
}
}
Consider this class:
public class MyClass : INotifyPropertyChanged
{
private int _id;
private string _value;
public int Id
{
get
{
return _id;
}
set
{
PropertyChanged(this, new PropertyChangedEventArgs("Id"));
_id = value;
}
}
public string Value
{
get
{
return _value;
}
set
{
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
_value = value;
}
}
public event PropertyChangedEventHandler PropertyChanged = new PropertyChangedEventHandler(OnPropertyChanged);
private static void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// optional code logic
}
}
Add these methods to your sortable binding list:
public class SortableBindingList<T> : BindingList<T>, INotifyPropertyChanged
where T : class
{
public void Add(INotifyPropertyChanged item)
{
item.PropertyChanged += item_PropertyChanged;
base.Add((T)item);
}
void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
this.PropertyChanged(sender, new PropertyChangedEventArgs(String.Format("{0}:{1}", sender, e)));
}
// other content in the method body
}
And use this sample methods in your form:
public Form1()
{
InitializeComponent();
source = new SortableBindingList<MyClass>();
source.Add(new MyClass() { Id = 1, Value = "one test" });
source.Add(new MyClass() { Id = 2, Value = "second test" });
source.Add(new MyClass() { Id = 3, Value = "another test" });
source.PropertyChanged += source_PropertyChanged;
dataGridView1.DataSource = source;
}
void source_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
MessageBox.Show(e.PropertyName);
dataGridView1.DataSource = source;
}
private void button1_Click(object sender, EventArgs e)
{
((MyClass)source[0]).Id++;
}

How to add validation to PropertyGrid's CollectionEditor?

I'm using PropertyGrid to edit an object containing a collection.
Collection is edited using the CollectionEditor.
I have to make sure elements in collection are unique.
How can I add validation to CollectionEditor:
By either overloading CollectionEditor's OnFormClosing
Or adding validation for creating/editing items?
You can create your own collection editor, and hook into events on the default editor's controls. You can use these events to, say, disable the OK button. Something like:
public class MyCollectionEditor : CollectionEditor
{
private static Dictionary<CollectionForm, Button> okayButtons
= new Dictionary<CollectionForm, Button>();
// Inherit the default constructor from CollectionEditor
public MyCollectionEditor(Type type)
: base(type)
{
}
// Override this method in order to access the containing user controls
// from the default Collection Editor form or to add new ones...
protected override CollectionForm CreateCollectionForm()
{
CollectionForm collectionForm = base.CreateCollectionForm();
collectionForm.FormClosed +=
new FormClosedEventHandler(collectionForm_FormClosed);
collectionForm.Load += new EventHandler(collectionForm_Load);
if (collectionForm.Controls.Count > 0)
{
TableLayoutPanel mainPanel = collectionForm.Controls[0]
as TableLayoutPanel;
if ((mainPanel != null) && (mainPanel.Controls.Count > 7))
{
// Get a reference to the inner PropertyGrid and hook
// an event handler to it.
PropertyGrid propertyGrid = mainPanel.Controls[5]
as PropertyGrid;
if (propertyGrid != null)
{
propertyGrid.PropertyValueChanged +=
new PropertyValueChangedEventHandler(
propertyGrid_PropertyValueChanged);
}
// Also hook to the Add/Remove
TableLayoutPanel buttonPanel = mainPanel.Controls[1]
as TableLayoutPanel;
if ((buttonPanel != null) && (buttonPanel.Controls.Count > 1))
{
Button addButton = buttonPanel.Controls[0] as Button;
if (addButton != null)
{
addButton.Click += new EventHandler(addButton_Click);
}
Button removeButton = buttonPanel.Controls[1] as Button;
if (removeButton != null)
{
removeButton.Click +=
new EventHandler(removeButton_Click);
}
}
// Find the OK button, and hold onto it.
buttonPanel = mainPanel.Controls[6] as TableLayoutPanel;
if ((buttonPanel != null) && (buttonPanel.Controls.Count > 1))
{
Button okayButton = buttonPanel.Controls[0] as Button;
if (okayButton != null)
{
okayButtons[collectionForm] = okayButton;
}
}
}
}
return collectionForm;
}
private static void collectionForm_FormClosed(object sender,
FormClosedEventArgs e)
{
CollectionForm collectionForm = (CollectionForm)sender;
if (okayButtons.ContainsKey(collectionForm))
{
okayButtons.Remove(collectionForm);
}
}
private static void collectionForm_Load(object sender, EventArgs e)
{
ValidateEditValue((CollectionForm)sender);
}
private static void propertyGrid_PropertyValueChanged(object sender,
PropertyValueChangedEventArgs e)
{
ValidateEditValue((CollectionForm)sender);
}
private static void addButton_Click(object sender, EventArgs e)
{
Button addButton = (Button)sender;
ValidateEditValue((CollectionForm)addButton.Parent.Parent.Parent);
}
private static void removeButton_Click(object sender, EventArgs e)
{
Button removeButton = (Button)sender;
ValidateEditValue((CollectionForm)removeButton.Parent.Parent.Parent);
}
private static void ValidateEditValue(CollectionForm collectionForm)
{
if (okayButtons.ContainsKey(collectionForm))
{
Button okayButton = okayButtons[collectionForm];
IList<MyClass> items = collectionForm.EditValue as IList<MyClass>;
okayButton.Enabled = MyCollectionIsValid(items);
}
}
private static bool MyCollectionIsValid(IList<MyClass> items)
{
// Perform validation here.
return (items.Count == 2);
}
}
You will also need to add an Editor attribute to you collection:
class MyClass
{
[Editor(typeof(MyCollectionEditor),
typeof(System.Drawing.Design.UITypeEditor))]
List<Foo> MyCollection
{
get; set;
}
}
NOTE: I found that the value of items in removeButton_Click was not correct - so some tweaking may need to take place.
Try collectionForm.Context.Instance and typecast it to your data type this should do the trick.

Categories

Resources