I'm in the process of developing my first Windows Phone 7 Application. I'm freshfaced to Silverlight, C# and the whole .NET Scene, but I like to think I'm making decent progress.
I know from various code examples, I can set the tile using ShellTile. I know I can pass through params with the URI (Like this example):
ShellTile.Create(new Uri("/MainPage.xaml?DefaultTitle=FromSecondaryTile", UriKind.Relative), tile );
Can anyone point me in the direction (or explain) how I can handle arguments passed from the tile? So, when the tile's open, I'd like to open a certain part of the application.
For the record, I'm aware I could create a separate page for each one to handle it that way, but I can see that getting messy fast :)
Thanks!
Mike
A way I've found that works well for my particular purpose, is the same means of passing values between xaml pages, which is simply to pass them through in the query string:
NavigationContext.QueryString["XXXXX"].ToString();
Where XXXXX is the name in the key/name pair.
You can either set the url to a seperate page (like OtherPage.xaml) or you can use the supplied URI, and change the page/view in the OnNavigatedTo override.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
...
}
Here the NavigationEventArgs will provide you with the navigation args you supplied, as a regular dictionary. From those, you can decide what to do then.
Also, you can make life easier with a simple extension (here specialized with a overload for a integer key, since I personally prefer use them for identifiers)
namespace System.Windows.Navigation
{
public static class NavigationExtensions
{
public static int? TryGetKey(this NavigationContext source, string key)
{
if (source.QueryString.ContainsKey(key))
{
string value = source.QueryString[key];
int result = 0;
if (int.TryParse(value, out result))
{
return result;
}
}
return null;
}
public static string TryGetStringKey(this NavigationContext source, string key)
{
if (source.QueryString.ContainsKey(key))
{
return source.QueryString[key];
}
return null;
}
}
}
Related
Please help me with this question. I'm coding come ability system in Unity3D 2019.4.1 (if you might want to know) and have had created "Roller" class for some random numbers. There is
public static Func<Creature, int> OnNumberRolled;
in "Roller" class. Some of abilities in my game must know about these random numbers and when they are rolled, they invoke some mess.
Here is an ability class:
public class ListenerEffect : Effect
{
public int OnRolledOne(Creature creature)
{
...
}
public override void CastEffect(ITargetable caster, ITargetable target)
{
Creature localCasterCreature = caster as Creature;
Roller.OnNumberRolled += OnRolledOne(localTargetCreature);
}
}
At this moment
Roller.OnNumberRolled += OnRolledOne(localTargetCreature);
error occurs. It says that it can't convert "int" into "System.Func<Creature, int>". Both classes are using System. What should I do?
Just use the name of the function. Otherwise, you are calling the function and are using the returned value.
Roller.OnNumberRolled += OnRolledOne;
If you add several handlers, keep in mind that the return values will be lost (but the last one) on invocation as OnNumberRolled().
You might have the handlers to add their results to a list or something like that, but we would need more insight on your use cases to design a satisfactory solution.
You can also iterate on handlers like this:
var handlers = OnNumberRolled.GetInvocationList();
foreach (var handler in handlers)
{
// invoke and handle each handlers'result here
Debug.Log(handler());
}
I have the following function:
public void Test(string testString)
{
//Do Stuff
}
At some points in my code, I have to repeatedly check if the parameter is empty string/null/whitespace to skip the body method. The usual ways I've done this till now, are the following:
public void Test(string testString)
{
if(!string.IsNullOrWhiteSpace(testString))
{
//Do Stuff only if string has text in it.
}
}
Or
public void Test(string testString)
{
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
Is there a way to create a custom attribute that checks if the parameter of the function is empty etc, to skip the method? I've had some experiece (basic stuff), with custom attributes, but I can't figure out a way to make the attribute skip the method body.
The ideal end product of the implementation would be the following:
[SkipIfEmptyParameter]
public void Test(string testString)
{
//Do Stuff only if string has text in it.
}
Of course, any suggestion is welcome that helps minimize the recurring code if the attribute implementation is not possible.
Edit: Example of the problem I want to solve.
I have the following methods. I get from Microsoft Test Manager, some parameters that our test scenario are expecting (what the values should be). There is a SharedStep implementation that asserts the user's info:
public void AssertUser(UserDTO expectedUserInfo)
{
VerifyUserName(expectedUserInfo.name);
VerifyUserSurname(expectedUserInfo.surname);
VerifyUserAge(expectedUserInfo.age);
VerifyUserHeight(expectedUserInfo.height);
}
private void VerifyUserName(string name)
{
//If the string parameter is empty, means the MTM scenario does not
//want to validate the user's name at this point, so skip the
//verification below.
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
private void VerifyUserSurname(string surname)
{
//If the string parameter is empty, means the MTM scenario does not
//want to validate the user's surname at this point, so skip the
//verification below.
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
private void VerifyUserAge(string age)
{
//If the string parameter is empty, means the MTM scenario does not
//want to validate the user's age at this point, so skip the
//verification below.
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
private void VerifyUserHeight(string height)
{
//If the string parameter is empty, means the MTM scenario does not
//want to validate the user's height at this point, so skip the
//verification below.
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
The "Do Stuff" contain Selenium implementation that handle WebElements and might be time consuming, so if we don't want to validate that specific value, we just skip the whole method.
Now, when creating the scenarios over to Microsoft Test Manager, the shared steps allows the tester to decide what elements of the page will be validated. If some of the parameters are empty, then the code just skips the blocks and goes to w/e validation the user wants (still, the implementation is for every info the user has, but we just assign value to each parameter we want to test, and every parameter that does not have a value, just gets it's method body skipped).
The problem is, if I want to change the condition of skipping the method, I will have to go to each method and manually change the IF statement. Hence why I though it might be a good idea to have an attribute for every method that validates information.
P.S. I'm talking about hundreds of methods that have the IF implementation at the start.
The only way that I know that this can be done using attributes is aspect oriented programming using a product like post sharp and method interception. Alternatively if the methods are defined in an interface this can also be done by using RealProxy but seems more than a little overkill.
The way you are doing it is actually pretty good. But as Evk pointed out in the comments: You should extract the "skip checking" into a separate method, especially if the check is always the same and needs to be changed globally. Using an attribute would solve the problem, but is a little complicated to use.
Instead, take a look at the code below. Looks pretty clear, doesn't it? Don't use too many comments (and don't copy-paste them into every method, that is of no use). This way, you have the same benefits as if you would use a custom attribute but without the ugliness of using reflection.
public void AssertUser(UserDTO expectedUserInfo)
{
VerifyUserName(expectedUserInfo.name);
VerifyUserSurname(expectedUserInfo.surname);
VerifyUserAge(expectedUserInfo.age);
VerifyUserHeight(expectedUserInfo.height);
}
private void VerifyUserName(string name)
{
if (ShouldSkipValidation(name)) return;
// code here...
}
private void VerifyUserSurname(string surname)
{
if (ShouldSkipValidation(surname)) return;
// code here...
}
private void VerifyUserAge(string age)
{
if (ShouldSkipValidation(age)) return;
// code here...
}
private void VerifyUserHeight(string height)
{
if (ShouldSkipValidation(height)) return;
// code here...
}
// The MTM scenario does not want to validate values that satisfy the check below
private bool ShouldSkipValidation(string value)
{
return string.IsNullOrWhiteSpace(value) || value == "<>";
}
I don't think attributes make it possible to achieve what you are trying to achieve.
But you can use a custom method invoker instead:
static void Main(string[] args)
{
InvokeIfNotNullOrWhitespace((inputStr) => TestMethod(inputStr), null);
InvokeIfNotNullOrWhitespace((inputStr) => TestMethod(inputStr), "");
InvokeIfNotNullOrWhitespace((inputStr) => TestMethod(inputStr), "abc");
// RESULT:
// Trying to invoke action...
// Trying to invoke action...
// Trying to invoke action...
// I have been invoked!
}
static void InvokeIfNotNullOrWhitespace(Action<string> action, string inputString)
{
Console.WriteLine("Trying to invoke action...");
if(!string.IsNullOrWhiteSpace(inputString))
action.DynamicInvoke(inputString);
}
static void TestMethod(string input)
{
Console.WriteLine("I have been invoked!");
}
The reason why I think attributes won't work is because they can't control what is going on inside the method. Instead, "other external things" can look at those attributes and decide what to do.
To achieve what you are trying to achieve, an "external thing" would need to look at the attribute and decide if it is executed or not. This would be equivalent to what I wrote: an external invoker that unifies the "check string validity" procedure.
Here are my 4 cents on this,
Calling an attribute involves reflection, already a bad idea as
you need to find out if the attribute is set;
You're avoiding a "1 liner" in your code that actually is quite
easy to type;
Use method overloading;
You can use Aspect oriented programming that will basically inject the below samples in your code at compile time. You can control the way this works with annotations and would not have a negative effect on the generated runtime.
Here are some variations:
//1
if(string.IsNullOrEmpty(testString))
return;
//2
if(string.IsNullOrEmpty(testString) ||string.IsNullOrWhiteSpace(testString) )
return;
When going for 3 just make sure you do not mix returning null, or boolean true/false based on the "missing" text. Only you know how your code should flow.
Perhaps you are looking for method overloading
you can do that by creating 2 methods with the same name in the same class.
You can call the empty MyMethod() from the MyMethod(with string) so you do not duplicate the logic.
return string.IsNullOrEmpty(testString)?MyMethod():MyMethod(testString);
I'm new to Windows Phone and C#, enjoying the change from Objective-C and Java.
I cant find the way to pass an object from one class to another. I came across some sample code looking on MSDN but I tink that maybe its not applicable for what I need.
private void meetingList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (meetingList.SelectedIndex != -1)
{
Meeting aMeeting = (Meeting)meetingList.SelectedItem;
this.NavigationService.Navigate(new Uri("/MeetDetails.xaml", UriKind.Relative));
ApplicationBar.IsVisible = true;
}
}
How can I pass my Meeting Object 'aMeeting' into my MeetDetails class so that I can display all the details to the user.
I know I can break it down, and pass in all the vars from the 'aMeeting' by using something like this:
this.NavigationService.Navigate(new Uri("/MeetDetails.xaml?Meeting=" +
aMeeting.meetName + "&TheDate=" +
aMeeting.meetDate, UriKind.Relative));
Is there something I've missed? Are there alternative ways you guys would recommend?
Many Thanks,
-Code
What you've posted is a good way of transferring simple data about the place. However it becomes a pain when you have to pass a complex object between pages.
The recommended way is to use the MVVM pattern (from wikipedia and MSDN). This gives you a way to separate the View from everything else by making use of data binding. The best tutorials I have seen is to watch the videos on MSDN.
var t1 = App.Current as App;
t1.SSIDToken = stData1SSID;
t1.CSRFToken = stData1CSRF;
this works real good, just make the members u need in the app.cs file
(here it was :
public string SSIDToken {get; set;}
public string CSRFToken {get; set;}
Then create the top code to create a var to serve as temp buffer.
If you want to get back the values use the same code :
var t1 = App.Current as App;
thisisatextbox.Text = t1.SSIDToken;
thisisalsoatextbox.Text = t1.CSRFToken;
Further info ;
http://www.eugenedotnet.com/2011/07/passing-values-between-windows-phone-7-pages-current-context-of-application/
EDIT: After a couple of months of experience, noticed you can add
public static new App Current
{
get { return Application.Current as App; }
}
In the App.xaml (In the public class App) to be able to call upon App.Current without having to declare it every single time!
Now you can use App.Current.CSRFToken = "" || string CSRFTk = App.Current.CSRFToken;
You might want to consider a manager class with properties which could store your current Meeting object. This would then be set in your SelectionChanged event handler and then accessed in your MeetDetails page. The manager class is defined externally to your pages so that it can be accessed from all your pages.
I'll admit sometimes the deeper nuances of the keyword static escape me.
Here's what I'm seeing:
public partial class Default : CSSDEIStatusBase
{
private static Default _csWitWeb;
protected void Page_Load(object sender, EventArgs e)
{
//DoStuff
_csWitWeb = this;
//OtherStuff
}
public static void ForceLoadSyncOperation(int? index)
{
Default._csWitWeb.LoadSelectedSyncOperation(index);
}
}
The only references to ForceLoadSyncOperation are:
Default.ForceLoadSyncOperation(index);
or
Default.ForceLoadSyncOperation(null);
Both of these calls originate from:
public partial class DataOriginUserControl : System.Web.UI.UserControl
and are not located inside of static methods.
E.G:
protected void btnCancelSyncOperation_Click(object sender, EventArgs e)
{
this.lblErrorMessage.Text = string.Empty;
this.lblErrorMessage.Visible = false;
int index = _syncOperation.Sequence - 1;
Default.ForceLoadSyncOperation(index);
}
This all seems really quirky to me. Does this smell to anyone else? Not really sure how to untangle it, though, as I can't exactly create an instance of the Default page inside of a user control.
Thoughts? Thanks for reading.
protected void LoadSelectedSyncOperation(int? index)
{
SyncOperationConfiguration[] syncOperations = CSServiceClient.GetInterfaceConfiguration().SyncOperationConfigurations.ToArray();
PopulateSyncOperationsListView(syncOperations);
SyncOperationConfiguration syncOperation = null;
try
{
syncOperation = syncOperations[index.HasValue ? index.Value : 0];
}
catch
{
syncOperation = syncOperations[0];
}
ucDataOrigin.LoadSyncOperationData(syncOperation);
Session["ConfigMenuActiveIndex"] = 1;
menuConfiguration.Items[(int)Session["ConfigMenuActiveIndex"]].Selected = true;
mvwConfiguration.ActiveViewIndex = (int)Session["ConfigMenuActiveIndex"];
}
Presumably, the user control is contained within the Default page and the static member is being used as a shortcut to get the current instance of Default. I would've done it this way:
Default defaultPage = this.Page as Default;
if (defaultPage != null)
{
defaultPage.LoadSelectedSyncOperation(index);
}
Using a static member in this way is not safe. It opens up the door for race conditions. There is the potential risk that the user control is loaded in another page and calls LoadSelectedSyncOperation() on a separate request's instance of Default, thus wreaking all kinds of potential havoc.
I don't know what LoadSelectedSyncOperation does but this code looks weird. Whenever you click btnCancelSyncOperation you end up calling this method on some page, but you never know on which of them. It doesn't make much sense to me.
I would definitely say your concerns are valid. I can't think of any reason that this design would make sense, ever. This would throw a flag for me, too.
Based on your reply to my comment, if the Default.LoadSelectedSyncOperation is not dependent upon the Default page somehow, then I suggest it be refactored into a separate class (not an ASP.NET Page).
Whether it makes sense for the method or new class to be static or not is a separate concern and would be based on the logic contained within the method.
I have an event handler for the TextBox.TextChanged event on a form of mine. In order to support undo, I'd like to figure out exactly what has changed in the TextBox, so that I can undo the change if the user asks for it. (I know the builtin textbox supports undo, but I'd like to have a single undo stack for the whole application)
Is there a reasonable way to do that? If not, is there a better way of supporting such an undo feature?
EDIT: Something like the following seems to work -- are there any better ideas? (It's times like this that I really wish .NET had something like the STL's std::mismatch algorithm...
class TextModification
{
private string _OldValue;
public string OldValue
{
get
{
return _OldValue;
}
}
private string _NewValue;
public string NewValue
{
get
{
return _NewValue;
}
}
private int _Position;
public int Position
{
get
{
return _Position;
}
}
public TextModification(string oldValue, string newValue, int position)
{
_OldValue = oldValue;
_NewValue = newValue;
_Position = position;
}
public void RevertTextbox(System.Windows.Forms.TextBox tb)
{
tb.Text = tb.Text.Substring(0, Position) + OldValue + tb.Text.Substring(Position + NewValue.Length);
}
}
private Stack<TextModification> changes = new Stack<TextModification>();
private string OldTBText = "";
private bool undoing = false;
private void Undoit()
{
if (changes.Count == 0)
return;
undoing = true;
changes.Pop().RevertTextbox(tbFilter);
OldTBText = tbFilter.Text;
undoing = false;
}
private void UpdateUndoStatus(TextBox caller)
{
int changeStartLocation = 0;
int changeEndTBLocation = caller.Text.Length;
int changeEndOldLocation = OldTBText.Length;
while (changeStartLocation < Math.Min(changeEndOldLocation, changeEndTBLocation) &&
caller.Text[changeStartLocation] == OldTBText[changeStartLocation])
changeStartLocation++;
while (changeEndTBLocation > 1 && changeEndOldLocation > 1 &&
caller.Text[changeEndTBLocation-1] == OldTBText[changeEndOldLocation-1])
{
changeEndTBLocation--;
changeEndOldLocation--;
}
changes.Push(new TextModification(
OldTBText.Substring(changeStartLocation, changeEndOldLocation - changeStartLocation),
caller.Text.Substring(changeStartLocation, changeEndTBLocation - changeStartLocation),
changeStartLocation));
OldTBText = caller.Text;
}
private void tbFilter_TextChanged(object sender, EventArgs e)
{
if (!undoing)
UpdateUndoStatus((TextBox)sender);
}
You might be better off using the Enter and Leave events instead. When entering, store the current text in a class variable, then when leaving compare the new text to the old.
Yes, don't tie it directly to the textbox. Your forms' state should be in some model object somewhere that isn't directly tied to the form (MVC is one way to do this, MVVM is another). By decoupling them like that, you can compare the new textbox value to the current model value whenever a change request comes in.
Actually, all I can think of is having some kind of collection where you store different string versions (so you can undo many times, not just once).
I would store the reference to TextBox's collections in TextBox.Tag, so it is straightforward to store/use it.
Last but not least, you update your collection of strings during the event TextChange. With no much work, you can maintain a full history, gettinjg the previous value from your own structure.
This is probably overkill for what you're trying to accomplish, but CSLA support n-level undo. CSLA is a great business objects framework written by Rocky Lhotka. The business objects handle the undo history and it flows to the UI through data binding.
Switching your app to use CSLA would be a big commitment, but another option would be to look through the freely available source code to see how he implemented it.
I am actually making an own Syntax-Highlight-System so I also need to know the changed text.
My solution is to watch for an enter or space or an depositioning of the cursor.
As WinForms provide the Keydown event I used the KeyEventArguments (e) and converted them to a char.
After that I storage the char into a string like :
string i="";
i+=convertedToChar; // convertedToChar = kc.ConvertToString(e.KeyData)
And as soon as there is a enter or space or depositioning - "event" I delete the string.
Result:
If a user enters a few chars and hit space I am able to read the last chars (till the last space).
An advantage would be the fact that you can use any delimiter char for that (as soon as they are storaged and provided by e.KeyCode)
However I hope that this is a solution for everybody watching this after 9years :D.
It´s never too late.