Binding Textblock with datacontext code behing - c#

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.

Related

How to subsequently update the radio button

I'm looping throught my database items and I'm displaying styled radio buttons and here's my code:
public ObservableCollection<Product> products = new ObservableCollection<Product>(ProductsController.SelectAllProducts());
if (products.Count > 0)
{
foreach(var item in products)
{
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush = (SolidColorBrush)(new BrushConverter().ConvertFrom("#004a80"));
RadioButton a = new RadioButton();
a.BorderThickness = new Thickness(1);
a.Background = Brushes.Green;
a.Foreground = new SolidColorBrush(Colors.Black);
a.BorderBrush = mySolidColorBrush;
a.Width = 118;
a.Height = 70;
a.Margin = new Thickness(5,0,0,5);
Style style = Application.Current.Resources["MyRadioButtonAsButtonStyle"] as Style;
a.Style = style;
a.ApplyTemplate();
a.Content = item.OrdinalNumber;
Image imgControl = (Image)a.Template.FindName("img", a);
Image imgControlWhite = (Image)a.Template.FindName("whiteImg", a);
TextBlock text = (TextBlock)a.Template.FindName("text", a);
a.Click += (object sender, RoutedEventArgs e) =>
{
var radioButton = sender as RadioButton;
MessageBox.Show(radioButton.Content.ToString());
};
text.Text = item.Title;
imgControl.Source = image;
spProducts.Children.Add(a);
}
}
On the beggining of my class I get all products from Db and I've created as many radio buttons as there are products and it looks like this:
If products.Count is 8 than we will see 8 radio buttons which are styled as buttons:
After while I would like to change background colour or title on the radio button but I would not like to refresh a whole screen so I've added INotifyPropertyChanged and product is list of type Product which looks like this:
public class Product : INotifyPropertyChanged
{
#region Attributes
private string _ordinalNumber;
private string _title;
private string _description;
#endregion
#region Properties
public string OrdinalNumber
{
get { return _ordinalNumber; }
set { _ordinalNumber = value; NotifyPropertyChanged("OrdinalNumber"); }
}
public string Title
{
get { return _title; }
set { _title = value; NotifyPropertyChanged("Title"); }
}
public string Description
{
get { return _description; }
set { _description = value; NotifyPropertyChanged("Description"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
And somewhere in my code in same file I've tried to modify a title:
var dbProduct = ProductController.Instance.GetProductByTitle(title);
var listItem = products.FirstOrDefault(x => x.OrdinalNumber == dbProduct.OrdinalNumber);
listItem.Title = "Test";
But nothing happened, I thought since products was source for creating radio buttons, so if I change Title of some item in that list it would affect radio button on screen since I'm using that Title prop while I'm displaying radio button text.
Any kind of help would be awesome.
You need to create a binding for changes to be tracked in the UI. Something like this:
Instead of -
text.Text = item.Title;
Have this -
Binding binding = new Binding("Title");
binding.Source = item;
BindingOperations.SetBinding(text, TextBlock.TextProperty, binding);

how to update custom control properties at design time immediately?

I created a custom Control which inherits from: Panel Control (using C# Class Library) then I used it inside a Form.
When I select any of the Control Properties (during design time), my custom control won’t update !
However if I close the Form and i reopen it; the changes will take place !
I want to have the Control updated when any of the Properties are changed.
Please find bellow my custom control code:
public class PersoCont : Panel
{
private int borderSize = 2;
private Color borderColor = Color.DarkRed;
private bool isBorder = true;
private int paddingTopTitle = 0;
private int paddingBorder = 0;
public int padding_TopTitle
{
get { return paddingTopTitle; }
set { paddingTopTitle = value; Invalidate(); }
}
public int padding_border
{
get { return paddingBorder; }
set { paddingBorder = value; Invalidate(); }
}
public int border_size
{
get { return borderSize; }
set { borderSize = value; Invalidate(); }
}
public Color border_color
{
get { return borderColor; }
set { borderColor = value; Invalidate(); }
}
public bool is_border
{
get { return isBorder; }
set { isBorder = value; Invalidate(); }
}
public PersoCont()
{
}
protected override void OnHandleCreated(EventArgs e)
{
if (this.Controls.Find("xlblTitle", true).Length == 0)
{
if (isBorder == true)
{
Label lblUp = new Label();
lblUp.Text = "";
lblUp.AutoSize = false;
lblUp.BackColor = borderColor;
int lblUpWidth = this.Width - (2 * paddingBorder) - (2 * borderSize);
lblUp.Size = new Size(lblUpWidth, borderSize);
lblUp.Location = new Point(borderSize + paddingBorder, paddingBorder);
lblUp.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
Label lblDown = new Label();
lblDown.Text = "";
lblDown.AutoSize = false;
lblDown.BackColor = borderColor;
lblDown.Size = new Size(lblUpWidth, borderSize);
int lblDownTop = this.Height - paddingBorder - borderSize;
lblDown.Location = new Point(borderSize + paddingBorder, lblDownTop);
lblDown.Anchor = AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right;
Label lblLeft = new Label();
lblLeft.Text = "";
lblLeft.AutoSize = false;
lblLeft.BackColor = borderColor;
int lblLeftHeight = this.Height - (2 * paddingBorder);
lblLeft.Size =new Size(borderSize,lblLeftHeight);
lblLeft.Location = new Point(paddingBorder, paddingBorder);
lblLeft.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom;
Label lblRight = new Label();
lblRight.Text = "";
lblRight.AutoSize = false;
lblRight.BackColor = borderColor;
lblRight.Size = new Size(borderSize, lblLeftHeight);
int lblRightLeft = this.Width - paddingBorder - borderSize;
lblRight.Location = new Point(lblRightLeft, paddingBorder);
lblRight.Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
this.Controls.Add(lblUp);
this.Controls.Add(lblDown);
this.Controls.Add(lblLeft);
this.Controls.Add(lblRight);
}
}
base.OnHandleCreated(e);
}
}
Use Refresh instead of Invalidate which only signals to the system that a repaint is needed, but won't actually do it: it will be a call to Refresh which will repaint it.
https://learn.microsoft.com/dotnet/api/system.windows.forms.control.refresh
https://learn.microsoft.com/dotnet/api/system.windows.forms.control.update
You may test if the internal value has changed, before calling Refresh to do it (only if necessary):
public int padding_TopTitle
{
get
{
return paddingTopTitle;
}
set
{
if ( paddingTopTitle != value )
{
paddingTopTitle = value;
Refresh();
}
}
}
You may consider using Framework Design Guidelines and C# Naming Conventions.
For example:
public int PaddingTopTitle
{
get
{
return paddingTopTitle;
}
set
{
if ( paddingTopTitle != value )
{
paddingTopTitle = value;
Refresh();
}
}
}
Or:
public int PaddingTopTitle
{
get
{
return _PaddingTopTitle;
}
set
{
if ( _PaddingTopTitle != value )
{
_PaddingTopTitle = value;
Refresh();
}
}
}
I personally prefer _PaddingTopTitle (or _paddingTopTitle) for private field of a property because paddingTopTitle is used for a method parameter as well as local var.
Therefore you may have for example : BorderSize and _BorderSize (or _borderSize).
Thank you for your help.
Initially I used the OnPaint event, but I really didn't like it because it would fire many times (I don't know why).
My problem was solved as follows:
I created a simple private method that will repaint (refresh the graphics data) according to all my properties. Now everything is working fine.
public class PersoCont2 : Panel
{
Label lblUp = null;
bool isBorder;
Color borderColor;
public bool is_border
{
get { return isBorder; }
set { isBorder = value; Rearrange( ); }
}
public Color border_color
{
get { return borderColor; }
set { borderColor = value; Rearrange( ); }
}
protected override void OnHandleCreated(EventArgs e)
{
Rearrange();
}
private void Rearrange( )
{
if( lblUp != null )
{
Controls.Remove( lblUp );
lblUp = null;
}
if( is_border )
{
lblUp = new Label( );
lblUp.BackColor = borderColor;
// TODO: set properties
// . . .
lblUp.Location = new Point( 10, 10 );
Controls.Add( lblUp );
}
}
}
You can try the following code to rewrite panel control and get what you want.
public class MyPanel : Panel
{
private Color colorBorder = Color.Transparent;
public MyPanel()
: base()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawRectangle(
new Pen(
new SolidBrush(colorBorder), 6),
e.ClipRectangle);
}
public Color BorderColor
{
get
{
return colorBorder;
}
set
{
colorBorder = value;
}
}
}
Result:
This behaviour however is a little bit awkward because it will only repaint after clicking the form designer.

How to create grid on button in Xamarin Forms

So I need to create a custom button, on what i have to create grid and on this grid I need to create several labels with specific informations.
This is code where i`m adding child to button
private void HighlightTodayDay()
{
Label label1 = new Label()
{
BackgroundColor = Color.DarkRed,
Text = "lbl1"
};
Label label2 = new Label()
{
BackgroundColor = Color.Gold,
Text = "lbl2"
};
if ((DateTime.Today.Year == actualVisibleMonth.Year) && (DateTime.Today.Month == actualVisibleMonth.Month))
{
foreach (var child in Children.Reverse())
{
if (child.ClassId.ToString() == ("actualDayButtonID" + DateTime.Today.Day.ToString()) && child.IsEnabled == true)
{
DayButton todayDayButton = dayButtonsList[DateTime.Today.Day + shiftOfFirstDay];
todayDayButton.TextColor = Color.FromHex("#0f0");
//upto this line everything is working as it should
todayDayButton.insideGrid.Children.Add(label1, 0, 0); //do nothing
todayDayButton.insideGrid.Children.Add(label2, 0, 1); //do nothing
return;
}
}
}
}
and here is code from "custom" button
class DayButton : Button
{
public string EventDate;
public string EventStartTime;
public string EventEndTime;
public string EventShift;
public string EventName;
public string EventDescription;
public Grid insideGrid;
public DayButton()
{
insideGrid = new Grid();
insideGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
insideGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(3, GridUnitType.Star) });
insideGrid.Parent = this;
}
}
It should look like this click to see image
you can add a GestureRecognizer to the Grid and then bind the tap event.
Ex of button code (now a ContentView):
class DayButton : ContentView
{
public string EventDate;
public string EventStartTime;
public string EventEndTime;
public string EventShift;
public string EventName;
public string EventDescription;
public Grid insideGrid;
public event EventHandler Clicked;
private TapGestureRecognizer _buttonTap;
private Lable _ButtonText;
public DayButton()
{
_ButtonText = new Lable
{
Text = EventName
}
insideGrid = new Grid
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
RowSpacing = 0,
RowDefinitions =
{
new RowDefinition {Height = GridLength.Auto} //0
},
ColumnDefinitions =
{
new ColumnDefinition {Width = GridLength.Star} //0
}
};
//Add your elements to the grid
insideGrid.Children.Add(_ButtonText, 0, 1, 0, 1)
//Set the grid as the content of this view
Content = insideGrid;
_buttonTap = new TapGestureRecognizer();
this.GestureRecognizers.Add(_buttonTap);
_buttonTap.Tapped += ButtonClicked;
}
}
private async void ButtonClicked(object sender, EventArgs e)
{
if (this.IsEnabled)
{
Clicked?.Invoke(this, e);
}
}
Then you can bind the "Clicked" event where you implement the button.
private DayButton _btn1 = new DayButton(){ EventName = "FooBaar"};
protected override void OnAppearing()
{
_btn1.Clicked += OnDayBtnClicked;
base.OnAppearing();
}
protected override void OnDisappearing()
{
_btn1.Clicked -= OnDayBtnClicked;
base.OnDisappearing();
}
private void OnDayBtnClicked(object sender, EventArgs e)
{
//What to do when a button is clicked
}
I decided to dismiss button and change it to stack layout (sick!) and to this stacklayout i`m adding new label with events!
soo code look like this:
public partial class Calendar : Grid
{...
public delegate void OnDayClickedDelegate(DateTime dateOfClickedDay);
public event OnDayClickedDelegate OnDayClicked;
...
private void DayClick(DateTime clickedDate)
{
OnDayClicked(clickedDate);
}
...
private void SomeVoid()
{...
DayLayout eventInDay = dayLayoutList[dayID];
var eventLabel = new Label
{
BackgroundColor = color,
Text = name.ToUpper(),
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
FontAttributes = FontAttributes.Bold
};
eventInDay.Children.Add(eventLabel);
...}
}
and day view
private class DayLayout : StackLayout
{
public delegate void OnClickedDelegate(DateTime dateOfClickedDay);
public event OnClickedDelegate OnClicked;
public Label DayNumber;
public DayLayout(DateTime day)
{
GestureRecognizers.Add
(
new TapGestureRecognizer
{
Command = new Command(() => OnClicked(day))
}
);
var dayNumber = new Label
{
HorizontalTextAlignment = TextAlignment.End,
VerticalTextAlignment = TextAlignment.Start,
Text = day.ToString("dd"),
FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label)),
FontAttributes = FontAttributes.Bold
};
DayNumber = dayNumber;
this.Children.Add(DayNumber);
}
}

UserControl Not Updating to Table

Problem
Problem only comes when I try to insert. However I could browse through records. When I insert a new record, the UserControl does not consider the value I typed in, instead it stores as null. I basically think on New record, it does not sync.
The Form Layout
Purpose of UserControl
The DB stores Field value in the form of JKB-932340094VN00 where I use my UserControl for split Values by - and display it in 2 TextBox in it. So one TextBox will have the Value of JKB and other will have 932340094VN00
UserControl is as follows:
public partial class ucClientAccountIDParser : UserControl, INotifyPropertyChanged
{
public ucClientAccountIDParser()
{
InitializeComponent();
id = "JKB-821230063VN00";
txtClientAccountID.TextChanged += new EventHandler(clientaccountIDChanged);
txtCustodyID.TextChanged += new EventHandler(custodyIDChanged);
}
private string _clientaccountID = string.Empty;
public string ClientaccountID
{
get { return _clientaccountID; }
set
{
_clientaccountID = value;
txtClientAccountID.Text = this._clientaccountID;
}
}
private string _custodyID = string.Empty;
public string CustodyID
{
get { return _custodyID; }
set
{
_custodyID = value;
txtCustodyID.Text = this._custodyID;
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
public string id = string.Empty;
[System.ComponentModel.Bindable(true)]
public string Text
{
get
{
return id;
}
set
{
id = value;
if (id != null)
{
string[] aVal = id.Split('-');
if (aVal.Length > 1)
{
this.CustodyID = aVal[0];
this.ClientaccountID = aVal[1];
}
else
{
this.ClientaccountID = id;
}
}
else
{
this.CustodyID = string.Empty;
this.ClientaccountID = string.Empty;
}
NotifyPropertyChanged(id);
}
}
public void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Text"));
}
}
private void clientaccountIDChanged(object sender, EventArgs e)
{
this.id = string.Format("{0}-{1}", txtCustodyID.Text, (sender as TextBox).Text);
NotifyPropertyChanged(this.id);
}
private void custodyIDChanged(object sender, EventArgs e)
{
this.id = string.Format("{0}-{1}", (sender as TextBox).Text, txtClientAccountID.Text);
NotifyPropertyChanged(this.id);
}
}
This is how I bind it:
try
{
this.Init(null);
this.Text = "General Account Add/Change";
objTable = new ClientAccountBusinessTable();
this.PrimaryDataAdapters = new ClientAccountBusinessTable[1] { objTable };
this.PrimaryDataGridView = null;
objTable.KeyDBField = "CLIENTID";
PrimaryBindingSource = new BindingSource[1] { bindingSource1 };
PrimaryDataSet.Tables.Add(objTable.GetBusinessTable());
SetKeyDBControl(new Control[1] { ucClientAccountIDParser1 }, new string[1] { "CLIENTID" });
ucClientAccountIDParser1.DataBindings.Clear();
ucClientAccountIDParser1.DataBindings.Add(new Binding("Text", this.bindingSource1, "CLIENTID"));
bindingSource1.DataMember = this.PrimaryDataSet.Tables[0].TableName;
bindingSource1.DataSource = this.PrimaryDataSet;
}
catch (Exception ex)
{
objTable = null;
throw ex;
}
I cant figure out why it takes null. Let me know if I carried out design of UserControl in proper way.
I hope anybody can help me out.

ASP.NET Boundfield overridden to support Dropdownlist is missing one final feature

I managed to override the Boundfield to display a dropdownlist if I put it in a Gridview.
protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
{
Control child = null;
Control cellControl = null;
if ((((rowState & DataControlRowState.Edit) != DataControlRowState.Normal) && !this.ReadOnly)
|| ((rowState & DataControlRowState.Insert) != DataControlRowState.Normal))
{
// If data cell is in edit mode, create DropDownList editor for this cell
// and set data properties.
DropDownList box = new DropDownList();
box.Items.Add(DefaultValueText);
box.DataSource = this.GetDataSource();
box.DataMember = this.BusinessObjectName;
box.DataTextField = this.DataTextField;
box.DataValueField = this.DataValueField;
box.AppendDataBoundItems = true;
box.ToolTip = this.HeaderText;
cell.Controls.Add(box);
box.DataBind();
// if in edit mode, prepare dropdown for binding
if ((this.DataField.Length != 0) && ((rowState & DataControlRowState.Edit) != DataControlRowState.Normal))
{
cellControl = box;
}
}
else if (this.DataField.Length != 0) // if in read only mode, prepare cell for binding
{
cellControl = cell;
}
if ((cellControl != null) && base.Visible)
{
cellControl.DataBinding += new EventHandler(this.OnDataBindField);
}
}
protected override void OnDataBindField(object sender, EventArgs e)
{
Control control = (Control)sender;
Control namingContainer = control.NamingContainer;
object dataValue = this.GetValue(namingContainer);
bool encode = (this.SupportsHtmlEncode && this.HtmlEncode) && (control is TableCell);
string str = this.FormatDataValue(dataValue, encode);
if (control is TableCell)
{
if (str.Length == 0)
{
str = " ";
}
((TableCell)control).Text = str;
}
else
{
//If data cell is in edit mode, set selected value of DropDownList
if (dataValue != null)
{
DropDownList dropDownList = (DropDownList) control;
ListItem itm = dropDownList.Items.FindByText(dataValue.ToString());
if (itm != null)
{
dropDownList.Text = itm.Value;
}
else
((DropDownList)control).Text = DefaultValueText;
}
}
}
The last feature I added is a default value/ additional item to display if nothing has been selected, like "please select" for example. I can set this through the property DefaultValueText in the OnDataBind event.
Now here's the problem I am facing:
In InitializeDataCell, if I set
box.AppendDataBoundItems = true;
and call
box.DataBind();
The dropdownlist has all the items plus the additional default item.
It also works nicely in the OnDataBind event, where I can now select the default if the databound item does not contain a value.
But when the dropdownlist is displayed in the gridview, it contains the default value plus everything from the datasource TWICE, because I set AppendDataBoundItems = true, which leads the dropdown to NOT clear it's items when items are added
The gridview must be calling databind twice, but it's only registering once in the OnDataBind event method. I only see one call there, and in that moment, everything is fine, the dropdown contains the default item plus one of each item from the datasource.
Any suggestions where or how I can handle the databinding so that I have full control over the databinding?
I managed to get it working
I moved all the code for setting the selectedValue to the DataBound event of the DropDownList. In this event, the databinding already happened and the list of values is available for me to set the selectedValue. I don't call DataBind myself anymore, since it's being called anyway on the control. I only add the "make a selection" item at the beginning and set AppendDataBoundItems to true.
There might be unhandled situations now in certain read only states, because I don't handle any Cell.Databinding() events.
Complete sourcecode for those who are interested...
It's based on the example from Javad Zarrinabadi at CodeProjct
usage:
DropDownBoundField dropDownBoundField = new DropDownBoundField();
dropDownBoundField.HeaderText = "NyColumnName";
dropDownBoundField.BusinessObjectName = "BusinessLogic.MyDataClass";
dropDownBoundField.SelectMethod = "GetEnumerable";
dropDownBoundField.DataTextField = "Name"; // what should be displayed
dropDownBoundField.DataValueField = "Id"; // value behind the displayed text
dropDownBoundField.DataField = "IdProperty"; // Property to bind to
dropDownBoundField.DefaultValueText = "Select"; // text on first item as
default if DataField is null
dropDownBoundField.FindBy = SetSelectedValueBy.Value // Choose how the DataField is being evaluated, as source for the value or the text
GridView.Columns.Add(dropDownBoundField);
Class:
using System;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;
using System.Web;
using System.Collections.Specialized;
namespace IDVCode.GridViews
{
public class DropDownField : BoundField
{
#region fields
private string _listDataSourceID;
private string _listDataMember;
private string _listDataTextField;
private string _listDataValueField;
#endregion
#region eventHandler
protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
{
DropDownList dropDownList = new DropDownList();
dropDownList.ToolTip = HeaderText;
dropDownList.DataSourceID = ListDataSourceID;
dropDownList.DataMember = ListDataMember;
dropDownList.DataTextField = ListDataTextField;
dropDownList.DataValueField = ListDataValueField;
dropDownList.Enabled = !ReadOnly;
cell.Controls.Add(dropDownList);
if (rowState == DataControlRowState.Normal || rowState == DataControlRowState.Alternate || ReadOnly)
{
dropDownList.Enabled = false;
}
if (DataField.Length != 0) // && ((rowState & DataControlRowState.Edit) != DataControlRowState.Normal))
{
dropDownList.DataBound += new EventHandler(OnDataBindField);
}
}
protected override void OnDataBindField(object sender, EventArgs e)
{
Control control = (Control)sender;
Control namingContainer = control.NamingContainer;
object dataValue = GetValue(namingContainer);
bool encode = (SupportsHtmlEncode && HtmlEncode) && (control is TableCell);
string str = FormatDataValue(dataValue, encode);
if (control is TableCell)
{
if (str.Length == 0)
{
str = " ";
}
((TableCell)control).Text = str;
}
else
{
if (!(control is DropDownList))
{
throw new HttpException("BoundField_WrongControlType");
}
if (((DropDownList)control).Items.Count > 0) // Don't call selectedValue if empty
{
if (dataValue != null)
{
DropDownList dropDownList = (DropDownList)control;
ListItem item = null;
if (FindBy == SetSelectedValueBy.Value)
{
item = dropDownList.Items.FindByValue(dataValue.ToString());
}
else
{
item = dropDownList.Items.FindByText(dataValue.ToString());
}
if (item != null)
dropDownList.Text = item.Value;
else
{
ListItem defaultItem = dropDownList.Items.FindByText(DefaultValueText);
if (defaultItem != null)
dropDownList.SelectedValue = defaultItem.Value;
}
}
}
}
}
public override void ExtractValuesFromCell(IOrderedDictionary dictionary, DataControlFieldCell cell,
DataControlRowState rowState, bool includeReadOnly)
{
Control control = null;
string dataField = DataField;
object text = null;
string nullDisplayText = NullDisplayText;
if (((rowState & DataControlRowState.Insert) == DataControlRowState.Normal) || InsertVisible)
{
if (cell.Controls.Count > 0)
{
control = cell.Controls[0];
DropDownList box = control as DropDownList;
if (box != null)
{
text = box.SelectedValue;
}
}
else if (includeReadOnly)
{
string s = cell.Text;
if (s == " ")
{
text = string.Empty;
}
else if (SupportsHtmlEncode && HtmlEncode)
{
text = HttpUtility.HtmlDecode(s);
}
else
{
text = s;
}
}
if (text != null)
{
if (((text is string) && (((string)text).Length == 0)) && ConvertEmptyStringToNull)
{
text = null;
}
if (((text is string) && (((string)text) == nullDisplayText)) && (nullDisplayText.Length > 0))
{
text = null;
}
if (dictionary.Contains(dataField))
{
dictionary[dataField] = text;
}
else
{
dictionary.Add(dataField, text);
}
}
}
}
#endregion
#region Properties
public virtual string ListDataSourceID
{
get
{
if (_listDataSourceID == null)
{
object stateBag = ViewState["ListDataSourceID"];
if (stateBag != null)
{
_listDataSourceID = (string)stateBag;
}
else
{
_listDataSourceID = string.Empty;
}
}
return _listDataSourceID;
}
set
{
if (!object.Equals(value, ViewState["ListDataSourceID"]))
{
ViewState["ListDataSourceID"] = value;
_listDataSourceID = value;
OnFieldChanged();
}
}
}
public virtual string ListDataMember
{
get
{
if (_listDataMember == null)
{
object stateBag = ViewState["ListDataMember"];
if (stateBag != null)
{
_listDataMember = (string)stateBag;
}
else
{
_listDataMember = string.Empty;
}
}
return _listDataMember;
}
set
{
if (!object.Equals(value, ViewState["ListDataMember"]))
{
ViewState["ListDataMember"] = value;
_listDataMember = value;
OnFieldChanged();
}
}
}
public virtual string ListDataTextField
{
get
{
if (_listDataTextField == null)
{
object stateBag = ViewState["ListDataTextField"];
if (stateBag != null)
{
_listDataTextField = (string)stateBag;
}
else
{
_listDataTextField = string.Empty;
}
}
return _listDataTextField;
}
set
{
if (!object.Equals(value, ViewState["ListDataTextField"]))
{
ViewState["ListDataTextField"] = value;
_listDataTextField = value;
OnFieldChanged();
}
}
}
public virtual string ListDataValueField
{
get
{
if (_listDataValueField == null)
{
object stateBag = ViewState["ListDataValueField"];
if (stateBag != null)
{
_listDataValueField = (string)stateBag;
}
else
{
_listDataValueField = string.Empty;
}
}
return _listDataValueField;
}
set
{
if (!object.Equals(value, ViewState["ListDataValueField"]))
{
ViewState["ListDataValueField"] = value;
_listDataValueField = value;
OnFieldChanged();
}
}
}
[Description("Sets a default value if applicable")]
[Category("Appearance")]
public string DefaultValueText
{
get
{
object val = ViewState["DefaultValueText"];
if (val != null)
{
return (string)val;
}
return (string.Empty);
}
set
{
ViewState["DefaultValueText"] = value;
}
}
[Description("Defines how the SelectedValue is set")]
[Category("Data")]
[DefaultValue(SetSelectedValueBy.Value)]
public SetSelectedValueBy FindBy
{
get
{
object val = ViewState["SetSelectedValueBy"];
return val != null ? (SetSelectedValueBy) val : SetSelectedValueBy.Value;
}
set
{
ViewState["SetSelectedValueBy"] = value;
}
}
public enum SetSelectedValueBy
{
Text,
Value
}
#endregion
}
}
Well, I know in some situations it does bind multiple times (upon changing criteria, etc.) so you are bound to deal with this issue again... can you clear the list and rebind?

Categories

Resources