I need to update BackColor of my ListBox by selecting the color from combobox and when clicked on the button.Here is my code
public Data _current;
public Data Current
{
get
{ return _current; }
set
{
_current = value;
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("Current"));
}
}
}
public Form1()
{
InitializeComponent();
Items = new ObservableCollection<Data>();
for (int i = 0; i < names.Count; i++)
{
Items.Add(new Data() {Name=names[i].ToString().TrimStart(new char[] { '[', 'C', 'o', 'l', 'o', 'r', ' ', ']' }).TrimEnd(new char[] { ']' }), color = names[i] });
}
comboBox1.DataSource = Items;
comboBox1.DisplayMember ="Name";
Current = Items.First();
}
public List<Color> names = new List<Color>() { Color.Red,Color.Yellow,Color.Green,Color.Blue };
public event PropertyChangedEventHandler PropertyChanged;
private void button1_Click(object sender, EventArgs e)
{
Current = comboBox1.SelectedItem as Data;
listBox1.DataBindings.Add("BackColor", Current, "color", true, DataSourceUpdateMode.OnPropertyChanged);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
public class Data:INotifyPropertyChanged
{
private Color _color;
public string name { get; set; }
public string Name
{
get
{ return name; }
set
{
name = value;
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
public Color color
{
get
{
return _color;
}
set
{
_color = value;
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("color"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Exception pop's out and says:"This causes two bindings in the collection to bind to the same property."
For solving your original problem "I need to update BackColor of my ListBox by selecting the color from combobox and when clicked on the button" you do not need databinding at all. You can just do it with
private void button1_Click( object sender, EventArgs e )
{
listBox1.BackColor = (Color)comboBox1.SelectedValue;
}
If you really want to do it with databinding, you can bind directly between listbox and combobox (ok, this does not involve a button click):
listBox1.DataBindings.Add( "BackColor", comboBox1, "SelectedValue", true, DataSourceUpdateMode.OnPropertyChanged );
If you need databinding and buttonclick you can bind combobox with form.Current
comboBox1.DataBindings.Add( "SelectedItem", this, "Current", true, DataSourceUpdateMode.OnPropertyChanged );
and update backcolor on button click:
private void button1_Click( object sender, EventArgs e )
{
listBox1.BackColor = Current.Color;
}
Here is the complete example incuding some more improvements:
public class Data : INotifyPropertyChanged
{
public string Name
{
get { return color.Name; }
}
private Color color;
public Color Color
{
get { return color; }
set
{
color = value;
if( PropertyChanged != null )
this.PropertyChanged( this, new PropertyChangedEventArgs( "Color" ) );
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class Form1 : Form
{
private ComboBox comboBox1;
private ListBox listBox1;
private Button button1;
public Form1()
{
InitializeComponent();
List<Data> dataList = new List<Data>
{
new Data { Color = Color.Red },
new Data { Color = Color.Yellow },
new Data { Color = Color.Green },
new Data { Color = Color.Blue },
};
comboBox1.DataSource = dataList;
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "Color";
}
public Data Current
{
get { return comboBox1.SelectedItem as Data; }
}
private void button1_Click( object sender, EventArgs e )
{
listBox1.BackColor = Current.Color;
}
private void InitializeComponent()
{
//...
}
}
You can bind any property of a control only once, otherwise you will receive an ArgumentException:
This causes two bindings in the collection to bind to the same
property. Parameter name: binding
In your code you have added data-binding in click event handler of button and each time you click the code executes.
To solve the problem, move data-binding code to Load event of form.
If for any reason you want to add binding in click event of button, to solve the problem you can check if the binding has not been added then add the binding:
if (listBox1.DataBindings["BackColor"] == null)
listBox1.DataBindings.Add("BackColor", Current, "color", true,
DataSourceUpdateMode.OnPropertyChanged);
I am making WPFToolkit based Graph where i am trying to update AreaSeries every time i click on a button.
I have implemented INotifyPropertyChanged on my data class. but when i reload the data in the source object id doesn't updates in chart(target object)
the code is as below:
public partial class MainWindow : Window
{
static List<Ready4LOS> Ready4LOS = new List<Data.Ready4LOS>();
public MainWindow()
{
InitializeComponent();
chart1.DataContext = Ready4LOS;
InitChart();
LoadData();
}
private void LoadData()
{
var path = #"zxzxzxz.log";
Ready4LOS.Clear();
List<APISTATDataModel> daa = APISTATDataModel.GetFromFile(path, new string[] { "|" }, "Ready4TOS");
List<APISTATDataModel> lastn = daa.GetRange(daa.Count - 10, 10);
foreach (APISTATDataModel d in lastn)
{
Ready4LOS.Add(new Ready4LOS() { Case = d.Current_Count, Time = d.Current_Time });
}
}
private void InitChart()
{
System.Windows.Data.Binding indi = new System.Windows.Data.Binding("Case");
System.Windows.Data.Binding dep = new System.Windows.Data.Binding("Time");
dep.Mode = System.Windows.Data.BindingMode.OneWay;
indi.Mode = System.Windows.Data.BindingMode.OneWay;
AreaSeries ares = new AreaSeries();
ares.ItemsSource = Ready4LOS;
ares.IndependentValueBinding = dep;
ares.DependentValueBinding = indi;
ares.Title = "Ready4LOS";
DateTimeAxis dta = new DateTimeAxis();
dta.Interval = 10;
dta.IntervalType = DateTimeIntervalType.Minutes;
dta.Title = "Time";
dta.Orientation = AxisOrientation.X;
// dta.Minimum = DateTime.Now.AddMinutes(-90);
// dta.Maximum = DateTime.Now;
LinearAxis yaxis = new LinearAxis();
yaxis.Minimum = 0;
yaxis.Interval = 2;
yaxis.Title = "Case";
yaxis.Orientation = AxisOrientation.Y;
yaxis.ShowGridLines = true;
chart1.Axes.Add(yaxis);
chart1.Axes.Add(dta);
chart1.Series.Add(ares);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
LoadData();
chart1.UpdateLayout();
}
}
}
the data model is here
class Ready4LOS : INotifyPropertyChanged
{
int _case;
DateTime _time;
public int Case
{
get
{
return _case;
}
set
{
_case = value;
NotifyPropertyChanged("Case");
}
}
public DateTime Time
{
get
{
return _time;
}
set
{
_time = value;
NotifyPropertyChanged("Time");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
It loads perfectly when it starts as i've called the LoadData() in the beginning.
The problem is when i click on the refresh button it loads the data in the source object but the target object's data in not updated i.e. chart is not updated it remains the same as of initial data.
Use ObservableCollection<Ready4LOS>, not List<Ready4LOS>. ObservableCollection<> already implements INotifyPropertyChanged and also INotifyCollectionChanged. Your implementation of INotifyPropertyChanged for Ready4LOS may only be necessary if you're going to dynamically change values for Case and Time for existing Ready4LOS already in your collection.
I want to bind a border generated dynamically from code behind.
below is my model that I bind with the border.
public class MapTextboxGridModel : INotifyPropertyChanged
{
private MaptextBoxGridStylePropertiesModel _GridStyleProperties = new MaptextBoxGridStylePropertiesModel();
public MaptextBoxGridStylePropertiesModel GridStyleProperties
{
get { return _GridStyleProperties; }
set
{
_GridStyleProperties = value;
OnPropertyChanged("GridStyleProperties");
}
}
}
My style for each cells is in the _GridStyleProperties. And in _GridStyleProperties model I have one property "_Name" as below.
public class MaptextBoxGridStylePropertiesModel : INotifyPropertyChanged
{
private string _Name = "Enter your text";
public string Name
{
get { return _Name; }
set
{
_Name = value;
OnPropertyChanged("Name");
}
}}
// following border(multiple, so I will have border in each cell of the grid) is created inside a grid
MapTextboxGridModel cellcontext = new MapTextboxGridModel();
Border db = new Border();
db.MouseLeftButtonDown += db_MouseLeftButtonDown;
db.DataContext = cellcontext;
TextBlock block = new TextBlock() { Text = cellcontext.GridStyleProperties.Name };
and then when I click on any of the cell in the grid.
void db_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (columnpossition == -1 && rowpossition == -1)
{
columnpossition = Grid.GetColumn(sender as Border);
rowpossition = Grid.GetRow(sender as Border);
}
else
{
Border bod = sender as Border;
Grid grd = bod.Parent as Grid;
int col = Grid.GetColumn(bod);
int row = Grid.GetRow(bod);
if (col == columnpossition && row == rowpossition)
{
}
else
{
TextBlock dbtxt = bod.Child as TextBlock;
imodel.GridStyleProperties.needtoshow = true;
Binding textbnd = new Binding();
textbnd.Source = bod.DataContext as MapTextboxGridModel;
textbnd.Path = new PropertyPath("StyleProperties.Name"); // Is this possible
BindingOperations.SetBinding(dbtxt, TextBlock.TextProperty, textbnd);
columnpossition = col;
rowpossition = row;
}
}
}
I can't understand where am I making mistake. Please suggest me what change should be done in above code.
I am new to Xamarin.Forms and the binding concept. Can someone please tell me why this is not working? The name of the object itself is changing when I'm pressing the button. Why wont the Text-property update?
var red = new Label
{
Text = todoItem.Name,
BackgroundColor = Color.Red,
Font = Font.SystemFontOfSize (20)
};
red.SetBinding (Label.TextProperty, "Name");
Button button = new Button
{
Text = String.Format("Tap for name change!")
};
button.Clicked += (sender, args) =>
{
_todoItem.Name = "Namie " + new Random().NextDouble();
};
The todoItem is an object of the class below. The notification itself works, I am almost positive. I guess there's something wrong with my binding, or I am missing something with this concept.
public class TodoItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string _name;
public string Name
{
get { return _name; }
set
{
if (value.Equals(_name, StringComparison.Ordinal))
{
// Nothing to do - the value hasn't changed;
return;
}
_name = value;
OnPropertyChanged();
}
}
void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
You need to set the Label's BindingContext:
red.BindingContext = _todoItem;
I have the following object:
public class Notification : INotifyPropertyChanged
{
private bool _trafficNot;
public bool TrafficNot
{
get { return _trafficNot; }
set {
if (value.Equals(_trafficNot))
return;
_trafficNot = value;
OnPropertyChanged();
}
}
private bool _newsNot;
public bool NewsNot
{
get { return _newsNot; }
set
{
if (value.Equals(_newsNot))
return;
_newsNot = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName]String propertyName=null)
{
var handler=PropertyChanged;
if(handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I get the data from an a object like this:
//set up the notification object according to what is stored in the DB
Notification notification = new Notification
{
TrafficNot = uInfo.NotificationTraffic,
NewsNot = uInfo.NotificationNews
};
and I want to bind the data to these switchells
TableView tableView = new TableView
{
BindingContext = notification,
Intent = TableIntent.Form,
Root = new TableRoot
{
new TableSection
{
new SwitchCell
{
Text = "News",
BindingContext = "NewsNot"
},
new SwitchCell
{
Text = "Traffic",
BindingContext = "TrafficNot"
},
new SwitchCell
}
}
};
What else do i need to do to bind it?
Cheers
You didn't bind view properties at all. Instead of assigning text to BindingContxt and Text property you should bind those Text properties, i.e.:
var sc = new SwitchCell();
sc.SetBinding(SwitchCell.TextProperty, new Binding("NewsNot"));
BindingContext is the source object while you are binding against its properties. See also DataBinding docs.