Problem code:
for (int i = 0; i <= numberOfPlayers - 1; i++)
{
if (i == dealerPosition())
{
StringBuilder sb = new StringBuilder();
// e.g. outputs "tbPosition1"
sb.Append("tbPosition").Append(dealerPosition().ToString());
// The following line of code does not work as sb is a string containing
// "thPosition1", not my controller tbPosition1. How do I fix this?
Dispatcher.Invoke(() => { (sb.Text = dealerPosition().ToString(); });
break;
}
}
Using C#, WPF, Visual Studio.
sb.Append("tbPosition").Append(dealerPosition().ToString());
// The following line of code does not work as sb is a string containing
// "thPosition1", not my controller tbPosition1. How do I fix this?
Dispatcher.Invoke(() => { ((this.FindName(sb.ToString()) as TextBox).Text = dealerPosition().ToString(); });
From Complexity's comment though, the post mentions that you can add all of your elements into the list and loop / foreach that when you want to work on it:
List<TextBox> textBoxesToEdit = new List<TextBox>(){tbposition1, tbposition2 /*so on*/};
foreach (TextBox textbox in textBoxesToEdit)
{
//do stuff
}
FindName() should help you with this, but note that you may have to may have to register each control as you create it if you add them after the control is initially created.
In line with your answer to my quetion I would store my tdPositionXYZ in an array or List and do this instead of all of your code:
Dispatcher.Invoke(() => {
tbPositionArray[dealerPosition()].Text = dealerPosition().ToString();
});
Related
I have a DumpContainer to which I'd like to add content dynamically. I know I can set the Content property to a new object but that gets rid of the previous content.
How can I add instead of replace?
Thanks for your help.
A couple more options:
If you want the items displayed vertically, but not in a table, use Util.VerticalRun inside a DumpContainer:
var content = new List<object>();
var dc = new DumpContainer (Util.VerticalRun (content)).Dump();
content.Add ("some text");
dc.Refresh();
content.Add (new Uri ("http://www.linqpad.net"));
dc.Refresh();
If the items are generated asynchronously, use an asynchronous stream (C# 8):
async Task Main()
{
// LINQPad dumps IAsyncEnumerables in the same way as IObservables:
RangeAsync (0, 10).Dump();
}
public static async IAsyncEnumerable<int> RangeAsync (int start, int count)
{
for (int i = start; i < start + count; i++)
{
await Task.Delay (100);
yield return i;
}
}
If you are putting general objects in the DumpContainer that are displayed with field values, etc. you could convert to a similar (but without the Display in Grid button) format with Util.ToHtmlString and then concatenate.
var dc = new DumpContainer();
dc.Dump();
dc.Content = Util.RawHtml(Util.ToHtmlString(true, aVariable));
// some time later...
dc.Content = Util.RawHtml(Util.ToHtmlString(dc.Content)+Util.ToHtmlString(true, anotherVar));
Instead of adding content to the DumpContainer, go ahead and update it, but make its contents be something that has all the data you're trying to add.
var c = new DumpContainer();
var list = new List<string> {"message 1"};
c.Content = list;
c.Dump();
list.Add("message 2");
c.UpdateContent(list);
Alternatively, you can dump an IObservable<>, and it'll automatically get updated as objects are emitted. (Import the System.Reactive NuGet package to make this work.)
var s = new Subject<string>();
s.Dump();
s.OnNext("message 1");
s.OnNext("message 2");
So my issue is as follows, I am attempting to check all elements on the page and verify element.GetAttribute("class") == expectedClass. Here is the code
var feedback = Driver.FindElements(AuctivaSalesPageModel.ViewFeedbackSelector);
var attempts = 0;
foreach (IWebElement element in feedback)
{
while (attempts < 3)
{
try
{
Assert.AreEqual("leaveFeed actionTaken", element.GetAttribute("class"));
attempts = 0;
break;
}
catch (StaleElementReferenceException)
{
Assert.AreEqual("leaveFeed actionTaken", element.GetAttribute("class"));
attempts = 0;
break;
}
catch (AssertionException)
{
System.Threading.Thread.Sleep(3000);
Driver.Navigate().Refresh();
AuctivaSalesPage.WaitForElementVisible(Driver, AuctivaSalesPageModel.TotalNumberOfSalesSelector);
AuctivaSalesPage.ScrollToTop();
AuctivaSalesPage.SelectNoFolder();
attempts++;
}
}
}
Now I have been reading up on the StaleElementException and I think that my catch and retry approach is useless as if the DOM has refreshed then the element within the list will always be stale. I believe what I need to do here is refind the element with a Driver.FindElement() but being that I am encountering this issue within a foreach loop of IWebElements I am not sure how to get the selector for the specific element that is failing to retry?
Should I catch the exception rebuild the list and then retry the whole foreach loop? or is there a way to extract the selector specific to the element within the loop so I can do something along the lines of
Assert.AreEqual("leaveFeed actionTaken", Driver.FindElement(By.someSelector(element.GetSelector)).GetAttribute("class"));
I hope this helps, but i had a similar problem and was able to get around it using the following logic, granted its not the best approach but it works:
var feedbackCount = Driver.FindElements(AuctivaSalesPageModel.ViewFeedbackSelector).Count();
var attempts = 0;
for(var i = 0; i < feedbackCount; i++)
{
while (attempts < 3)
{
var element = Driver.FindElements(AuctivaSalesPageModel.ViewFeedbackSelector).ElementAt(i);
//Continue you logic here
}
}
Hope this help
I am using c# and sitecore to basically use tokens in certain places ( see: how to create a custom token in sitecore ). I think I have a solution, but am not sure as to why it is not working, even though I am getting no errors.
Item tokenItem = Sitecore.Context.Database.Items["/sitecore/content/Site Content/Tokens"];
if (tokenItem.HasChildren)
{
var sValue = args.FieldValue.ToString();
foreach (Item child in tokenItem.Children)
{
if (child.Template.Name == "Token")
{
string home = child.Fields["Title"].Value;
string hContent = child.Fields["Content"].Value;
if (sValue.Contains(home))
{
home.Replace(home, hContent);
}
}
}
}
home and hContent pull up the correct values of each container, but when the page loads, it still has the "home" value inputted (the ie: ##sales) in the content area instead of the new value, which is stored in hContent. The sValue contains everything (tables, divs, text) and I was trying to single out a value that equals to "home" and replace the "home" value with hContent. What am I missing?
If your code is implemented as a processor for the RenderField pipeline, you need to put the result of your work back into args. Try something like this:
Item tokenItem = Sitecore.Context.Database.Items["/sitecore/content/Site Content/Tokens"];
if (tokenItem.HasChildren)
{
var sValue = args.Result.FirstPart;
foreach (Item child in tokenItem.Children){
if (child.Template.Name == "Token") {
string home = child.Fields["Title"].Value;
string hContent = child.Fields["Content"].Value;
if (sValue.Contains(home)) {
sValue = sValue.Replace(home, hContent);
}
}
}
args.Result.FirstPart = sValue;
}
Note that you need to be sure to patch this processor into the pipeline after the GetFieldValue processor. That processor is responsible for pulling the field value into args.Result.FirstPart.
You code isn't really doing anything. You seem to be replacing the tokens on the token item field itself (child.Fields["Title"] and child.Fields["Content"]), not on the output content stream.
Try the following, you need to set the args to the replaced value, replacing both the FirstPart and LastPart properties: Replace Tokens in Rich Text Fields Using the Sitecore ASP.NET CMS (link to the code in the "untested prototype" link).
I would refactor your code to make it easier:
public void Process(RenderFieldArgs args)
{
args.Result.FirstPart = this.Replace(args.Result.FirstPart);
args.Result.LastPart = this.Replace(args.Result.LastPart);
}
protected string Replace(string input)
{
Item tokenItem = Sitecore.Context.Database.Items["/sitecore/content/Site Content/Tokens"];
if (tokenItem.HasChildren)
{
foreach (Item child in tokenItem.Children)
{
if (child.Template.Name == "Token")
{
string home = child.Fields["Title"].Value;
string hContent = child.Fields["Content"].Value;
if (input.Contains(home))
{
return input.Replace(home, hContent);
}
}
}
}
return input;
}
This is still not optimal, but gets you closer.
Well, Do you know what happens when you performs home.Replace(home, hContent);, it will create a new instance by replacing the content of the come with what is in hContent so what you need to do is, assign this instance to a new variable or to home itself. hence the snippet will be like the following:
if (sValue.Contains(home))
{
home = home.Replace(home, hContent);
}
Have you tried:
home = home.Replace(home,hContent);
I'm building an app for windows 8 desktop, I'm reading in a text file and I want to change one specific line but not sure how so what I have is a text file that says
username|false
username|false
username|false
And I want to remove the middle line when something happens, this is what I have so far;
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await folder.GetFileAsync("students.txt");
var text = await Windows.Storage.FileIO.ReadLinesAsync(storageFile);
var list_false = "";
foreach (var line in text)
{
string name = "" + line.Split('|')[0];
string testTaken = "" + line.Split('|')[1];
if (your_name.Text == name)
{
if (testTaken == "false") {
pageTitle.Text = name;
enter_name_grid.Opacity = 0;
questions_grid.Opacity = 1;
var md = new MessageDialog("Enjoy the test");
await md.ShowAsync();
}
else
{
the_name.Text = "You have already taken the test";
var md1 = new MessageDialog("You have already taken the test");
await md1.ShowAsync();
}
return;
}
else
{
list_false = "You're not on the list";
}
}
if (list_false == "You're not on the list") {
var md2 = new MessageDialog("You're not on the list");
await md2.ShowAsync();
}
Help please, it reads in names perfectly and allows them to take the test, I just need it to remove the correct line. Thanks in advance!!
The important thing to consider is that you are modifying a file. So whatever you choose to change then you need to write it back to the file.
In your case you are opting to read the whole file into memory, this actually works in your favor for something like this as you can just remove any unwanted lines and write back to the file. However, you cannot remove an item while you are iterating through the list using a foreach loop.
The best practice for removing items from an array you are looping is to use a for loop and loop in reverse. It also makes it easier to remove items if we work with a List<string> too, like so:
var list = new List<string>(text);
for(int i = text.Length - 1; i >=0; i--)
{
string line = text[i];
//rest of code
}
text = list.ToArray();
The next part of your task is to remove the line. You can do this in your else statement as this is the part that handles users already having taken the test. For example:
the_name.Text = "You have already taken the test";
list.RemoveAt(i);
Finally, after your loop you need to write the whole thing back to the file:
await Windows.Storage.FileIO.WriteLinesAsync(storageFile, text);
When you read the file, you could store the contents in a list. When your "something happens" you could remove the content at the appropriate index and save (overwrite) the list to the file.
First off.. I am new to asp.net and EF.
I have an EntityDatsource on my page I would like to loop through each row in the result set.
My goal is to dynamically build a page based on the values in the result set. Then to post the information back after it is edited by the user. My plan was to iterate each row on the page_load event. Currently I just have p-code in the area I would like to make this happen. The p-code is as follows
// foreach (DataRow row in AvailableDeviceConfigDataSource.enti Rows)
// {
// if sectionHeading <> lastSectionHeading
// {
// lastSectionHeading = sectionHeading
// AddSettingsSection(sectionHeading)
// }
// AddRowObjects
// }
Any guidance would be much appreciated.
In case anybody comes across this and is interested, I did solve my issue a while ago and figured I should post my answer for the benefit of others....
using (var context = new MyEntities())
{
string lastSectionHeading = "";
bool isFirstHeading = true;
var dynamicPageItems = context.view_dynamicPageItems;
foreach (var item in dynamicPageItems)
{
if (item.IsActive == 1)
{
if (!lastSectionHeading.Equals(item.CategoryId))
{
if (!isFirstHeading)
CloseSection();
lastSectionHeading = item.CategoryId;
AddSettingsSection(item.CategoryDescription);
isFirstHeading = false;
}
AddControl( item.DataType );
}
}
}