I'm trying to find a way to to do something that I think must be possible but I'm just missing the point on - so hopefully someone can give me a bit of a nudge :)
I'm utilising databinding in ASP.NET (viewstate turned off - so using controlstate for a few things here and there) to render a repeater (repeaterPriceClasses) that has a repeater within each itemtemplate (repeaterPriceBands). Basically this renders a table out of some text and a dropdownlist in each cell.
I'm trying to find a way to enumerate the repeaterOuter inside the event handler of a button to give me a list of all of the originally bound elements that have now got a dropdownlist with a value of >0, along with what that value is.
public Dictionary<Price, int> SelectedPrices
{
get
{
var sel = new Dictionary<Price, int>();
foreach(RepeaterItem itemClass in repeaterPriceClasses.Items)
{
var repeaterPriceBands = itemClass.FindControl("repeaterPriceBands") as Repeater;
foreach(RepeaterItem itemBand in repeaterPriceBands.Items)
{
var context = (Price)itemBand.DataItem;
var listQty = itemBand.FindControl("listQty") as DropDownList;
if(listQty.SelectedValue.ToInt32() > 0)
{
sel.Add(context, listQty.SelectedValue.ToInt32());
}
}
}
return sel;
}
}
Now this fails because the itemBand.DataItem is always null after databinding has finished.
What technique should I use to get around this?
Hidden field with primary keys in it
(not ideal as can be abused and adds
weight to the page)
Lookup from
original cached data based on indexes
(just seems wrong)
or something
else/better...?
EDIT: Is there any more information that I could provide to help this get answered?
You can try adding extra attributes to your HTML elements in the ItemDataBound event when DataItem is available.
ddlSomething.Attributes["Attribute1"] = dataItemObject.PropertyName;
[Edit]
Apart from using attributes, you can render some array containing JSON objects like this, for each row.
var repeaterItemAttributes = [ { Prop1: val1, Prop2: val2, ... }, { ... }, ... ]
So, by using this, you won't have to render the attributes, and your code will be XHTML compliant too (tho its not required). You can then loop through the object array and read any property you like. You can also apply the light encryption you were talking about to the property values.
[/Edit]
Related
I wish for my ListBox to update the old values with new values rather than simply adding more and more lines to the ListBox like it does at the moment. However, I'm not sure where to look to implement something that can handle this.
My current code looks like this:
private void DisplayText(string rawData)
{
textArduinoData.Text = rawData;
string[] sortedData = rawData.Split(';');
for (int i = 0; i < sortedData.Length; i++)
{
listPortData.Items.Add(sortedData[i].ToString());
}
}
Could someone please point me in the right direction to implementing this update feature? Any advice would be much appreciated.
You need to manage the process. It is easy in concept but depending on how much data is needed to be processed, it could get slow quickly. Steps
Create a specialized token class which implements to INotifyPropertyChanged.
Have an ObservableCollection hold the class items from #1. The observable collection notifies the ListBox when an item is added or removed. This will allow your code to add items one at a time. (Solves 1 problem)
To solve the next problem of data changing: Have a property named Text, on the class in #1 which will hold the data, provide a property change notification.
In the list box bind to the list of items created in step 1 and specify to bind to the Text. Use of a data template for the listbox will allow you to bind to the Text property of the list's instance.
Provide the heuristics/ smarts to read incoming data and find the associated data in the observable collection from step 2. When found change the Text property of the existing data to the new and the binding of that list item will change accordingly.
You could check if the ListBox contains the string using the IndexOf method and then update the existing string (or simply do nothing) or add a new one depending on whether you get an index other than the default value of -1 back:
private void DisplayText(string rawData)
{
textArduinoData.Text = rawData;
string[] sortedData = rawData.Split(';');
int index;
for (int i = 0; i < sortedData.Length; i++)
{
if ((index = listPortData.Items.IndexOf(sortedData[i])) == -1)
{
listPortData.Items.Add(sortedData[i]);
}
}
}
Goal - To cycle through a Tableview and obtain the input field type and value, ignoring label. The view is entirely based in c# code as the tableview will vary constantly.
So far in a for each look I can cycle through to the point of:
var x = (object)myViewCellInputItem[0];
For now I have set up a textview which has two elements, label and entry. The entry object I can obtain in var x as above.
Goal: Get the "Text" attrtibute.
Entry ent = (Entry)x;
string text = ent.Text;
The code above achives it. What I am face with is other Views such as DatePicker etc.
I was considering:
private string GetProperty(object XamarinObj)
{
string output;
Type t = XamarinObj.GetType();
if (t == typeof(Xamarin.Forms.Entry))
{
Entry ent = (Entry)XamaninObj;
return ent.Text.ToString();
}
else if {
.... repeat for other types
}
}
A unhelpful friend suggested to use Linq to query x to find "Text", "Items", "Date" etc but wouldn't show me how!
Your thoughts.
Well after much searching this is the route I went down. I can obtain all View/Text/Cell data I wish across all three platforms.
I'm having trouble accessing the value of a calculated field from a list which is in a lookup field on another list in codebehind for SharePoint.
A ListFieldIterator on a page displays a load of options to a user. I need to perform some back-end validation on some particular selections the user has made.
I have a list called "Event Type" from which a user can select Play, performance, display etc. This list has 4 columns - description, enabled, default and filtered. Filtered is a calculated column which is generated based upon the options chosen on the other columns.
The list Events has a column which is a lookup to this list, and which displays the filtered column.
Now on the page this all works great. The options are displayed to the user and they can make their selection. Before adding the calculated field I could access the choice made by doing the below
SPFieldLookup eventTypeField = ListFieldIterator.Item.Fields.GetField("Event_x0020_Type") as SPFieldLookup;
if (eventTypeField.GetFieldValueAsText(ListFieldIterator.Item["Event_x0020_Type"]) == "Performance")
{
// some other logic
errorMessages.Add("There is an error here");
}
Now however when accessing the field in this way I just get an empty string back.
If I attempt to access the chosen item with
string value = eventFields.Item["Event_x0020_Type_x0020_1"].ToString();
Then I get back "8" which is the position in the list of the item I chose. (it changes based on what item in the list I select)
This post Get value of calculate field seems related but I can't see an obvious way to get a calculated field from the lookupfield.
Any suggestions appreciated
It turns out that when using either a lookup column or a lookup column with a calculated field in, as I was, I was going about things the wrong way. This post put me onto the solution. The code is also below.
Essentially I need to access the value stored in the control of the ListFieldIterator and not the value from the item. The code below (from the link above) provides a nice way to do this.
public static List<T> GetControlsOfType<T>(this ControlCollection controls)
{
List<T> resultList = new List<T>();
foreach (Control control in controls)
{
if (control is T)
resultList.Add((T)((object)control));
if (control.Controls.Count > 0)
{
resultList.AddRange(GetControlsOfType<T>(control.Controls));
}
}
return resultList;
}
public object GetFieldValue(ListFieldIterator lfi, string fieldName)
{
FormField formField = lfi.Controls.GetControlsOfType<FormField>().Where(f => f.FieldName == fieldName).FirstOrDefault();
if (formField == null) return null;
return formField.Value;
}
I am stuck on this issue and cannot seem to find a way around it.
I have a CheckBoxList control. If you did not know, the FindControl() method on the CheckBoxList control returns "this". Microsoft did it because internally they dont create many ListItem objects but just one.
Anyway, I am trying to find out if a posted back control is one of the controls in my CheckBoxList. My code looks something along the lines of:
if (!(System.Web.UI.ScriptManager.GetCurrent(Page) == null)) {
string postbackControlId = System.Web.UI.ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID;
if (!string.IsNullOrEmpty(postbackControlId))
{
Control control = ControlFinder.RecursiveFindChildControl(Controls, postbackControlId);
if (!(control == null))
{ }
}
}
Is there anyway to enumerate the child controls of a CheckBoxList or find if an ID that I have is equal to one of theirs?
Thanks,
Mike
The UniqueID of a CheckBox within a CheckBoxList is the UniqueID of the CheckBoxList plus a $ plus the index of the item, so you can check whether postbackControlId is one of the CheckBox controls like this:
if (postbackControlId.StartsWith(this.checkBoxList.UniqueID + "$"))
{
int itemIndex = Convert.ToInt32(
postbackControlId.Substring(this.checkBoxList.UniqueID.Length + 1), 10);
// ...
}
If you're only looking to find out whether the postback was caused by one of the items in the CheckBoxList, you don't need to traverse the entire control hierarchy. You don't even need to drill down into the list. Something like this should work fine:
string elementID = ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID;
if (elementID.Contains(chkList.UniqueID))
{
//one of the checkboxes caused the postback
}
Hi I have a dictionary object implemented:
public partial class Window1 : Window
{
...
public Dictionary<string, string> Dictionarycheck = new Dictionary<string, string>();
public Window1()
{
Dictionarycheck.Add("Execbuildstartingmail", "Execbuildstartingmail");
Dictionarycheck.Add("Execbuildlastmail", "Execbuildlastmail");
...
}
}
then I have xml file to be parsed. I have more than 1 of such target to be parsed. I am supposed to parse the string of the attribute "if" so over here i would need "Execexample" as a string.
<project>
...
<target if="Execexample">
...
</target>
...
</project>
To do this parsing i tried to implement this code (which i'm not sure if it is correct):
private void xmlparsingButton_Click(object sender, RoutedEventArgs e)
{
XDocument xmlDoc = XDocument.Load(#"C:\Build.xml");
var abc = from target in xmlDoc.Descendants("target")
select (string)target.Attribute("if");
foreach(string target in abc)
{
// check this value whether if it exist in the dictionary.
// if not create a checkbox for it.
}
}
For the "foreach" statement i am supposed to do a check with the dictionary object. If there is no such value in dictionary, i will create a checkbox in my tabitem 5 and the name as the string (for example ExecexamplecheckBox).
how should i implement such a foreach function?
EDIT 1:
I forgot to add something. I need to write a text to a text file if these new checkboxes are checked. How do i do that? And they are required to write to a textfile that was written previously.
Does this solve the problem?
foreach(string target in abc)
{
//check this value whether if it exist in the dictionary. if not create a checkbox for it.
if (!Dictionarycheck.ContainsKey(target))
{
CheckBox chk = new CheckBox();
chk.Text = target;
SomePanel.Controls.Add(chk);
}
}
I can see two separate problems here:
1 - Data problem
Parse the xml file and extract the necessary data to a seperate list or dictionary.
2 - User interface
Generate a series of checkboxes based on the output of the data problem.
First you should separate the data problem away from the UI. In the foreach loop build a list of objects. The object should have at least a string property, for display, and a boolean property for the checkbox to bind to.
Second, on your UI create a ItemsControl (such as a ListBox) and bind its ItemsSource to the above list, then set the ItemTemplate to a DataTemplate containing a CheckBox
<ListBox ItemsSource="{Binding Path=SomeList}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Path=DisplayString}" IsChecked="{Binding Path=Selected}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
After the user has finished checking/unchecking the list, you will be left with a list upon which to write your text lines to a file.
There are several concepts you should learn when dealing with WPF, probably the hardest to get your head around is the seperation of concern between the UI and the data, and how the data layer can feed the UI to create elements for you. There should be no need to create new checkboxes in code using this technique.
Also, you will be better off not binding directly to a dictionary (although it is possible) but you should use ObservableCollection as your ItemsSource, it will handle change notification to the UI for you.
With the looks of it, as #Jackie mentioned, you could use HashSet. It won't make a difference except that it is the correct used of the right data structure in this case.
var filePath = "PathAndFileNameOfSomeFile.txt";
var hashset = new HashSet<string> { { "Execbuildstartingmail" }, { "Execbuildlastmail" } };
var xmlString = "<project><target if=\"Execexample\"></target><target if=\"Execbuildlastmail\"></target></project>";
var xDocument = XDocument.Parse(xmlString);
var attributeValues = from attrs in xDocument.Descendants("target").Attributes("if")
select attrs.Value;
foreach (var value in attributeValues)
{
var controls = this.Controls.Find(value, true);
//No checkbox with matching name found
if (controls.Length == 0)
{
if (!hashset.Contains(value))
{
var checkbox = new CheckBox();
checkbox.Parent = tabControl1.TabPages["tabPage2"];
checkbox.Text = value;
}
}
//checkbox with the given name was found AND is checked
else if (controls.Length == 1 && ((CheckBox)controls[0]).Checked)
{
using (var writer = File.AppendText(filePath))
{
writer.WriteLine(value);
}
}
}
After your Edit
I'm not clear about what you're saying in your edit, so I'll rephrase it...
While inthe foreach, if the checkbox exists and is checked, then you need to write some test to a text file. If they are not check there is nothing to do. If a checkbox does not exist, then add it to the tab is that correct?
I've updated the code to show you how to do three things:
Find Checkboxes in your form.
See if a checkbox is checked or not
Write some text to a text file.
even of the code I've provided does not do "Exactly" what you want I believe the various parts should help you get to your end goal. If not then please simply your question and provide very clear statements of where specifically you need help.