TextBox DataField always updating source bindings on text changed with text box that fails validation - silverlight-4.0

I have a TextBox with a two-way binding on the input. It is setup such that it fails validation if it is empty and displays a tooltip saying that it cannot be empty. My problem is that because it is failing validation, it tries to update the bindings everytime the text box changes (i.e. with every key press). I do not want it to update the source with every key press. I've narrowed it down to this code in the Silverlight 4.0 Tool kit for DataField.cs:
private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox != null && (ValidationUtil.ElementHasErrors(textBox) || !this._lostFocusFired[textBox]))
{
this._lostFocusFired[textBox] = false;
ValidationUtil.UpdateSourceOnElementBindings(textBox);
}
}
It is falling into the ValidationUtil.UpdateSourceOnElementBindings() because the element has errors. Is there anyway I can prevent it from doing this?

I think you want help rearranging your conditions to more accurately express your intent, but I'm not clear on what the existing code's result would be. This is why we ask for a complete, runnable (but minimal!) test case. However, if you simply don't want to update due to a failed validation, this should do the trick:
private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox != null && !this._lostFocusFired[textBox]))
{
ValidationUtil.UpdateSourceOnElementBindings(textBox);
}
}
You can validate the input and react to the result outside of that if statement.

Related

UWP "Invalid attribute value Unknown for property BorderThickness." while navigating to new Frame

While trying to navigate from one Page to another, I'm getting this "Invalid attribute value Unknown for property BorderThickness." error.
If I step through the code in the debugger everything works fine. If I let the navigation happen on it's own, the code crashes.
Outside of setting BorderThickness to specific (integer) values or using the built-in ThemeResources, these values are not ever tied to bound values that might be null or have an unexpected value.
This code was working fine at one point, but that seems to have come to an end this morning.
I'm still not certain why this is an issue, but I can identify specifically where the error is occurring.
public async void OnLevelUp(object sender, EventArgs e)
{
IsBusy = true;
LevelUpVm.CharacterId = IoC.Game.GetCharacter(SelectedCharacter.Id).Id;
**await IoC.SaveConfigFile();** <<< OFFENDING LINE OF CODE
var rootFrame = Window.Current.Content as Frame;
rootFrame?.Navigate(typeof(LevelUpView), null);
IsBusy = false;
}
If I move the OFFENDING LINE OF CODE after the rootFrame?Navigate line, it works fine.
So, after 5 hours of messing with the code, I've come to a solution - but I'm still not certain why the await call causes the problem.

Best way "select all" on a *form*? [duplicate]

I'm looking for a best way to implement common Windows keyboard shortcuts (for example Ctrl+F, Ctrl+N) in my Windows Forms application in C#.
The application has a main form which hosts many child forms (one at a time). When a user hits Ctrl+F, I'd like to show a custom search form. The search form would depend on the current open child form in the application.
I was thinking of using something like this in the ChildForm_KeyDown event:
if (e.KeyCode == Keys.F && Control.ModifierKeys == Keys.Control)
// Show search form
But this doesn't work. The event doesn't even fire when you press a key. What is the solution?
You probably forgot to set the form's KeyPreview property to True. Overriding the ProcessCmdKey() method is the generic solution:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == (Keys.Control | Keys.F)) {
MessageBox.Show("What the Ctrl+F?");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
On your Main form
Set KeyPreview to True
Add KeyDown event handler with the following code
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.N)
{
SearchForm searchForm = new SearchForm();
searchForm.Show();
}
}
The best way is to use menu mnemonics, i.e. to have menu entries in your main form that get assigned the keyboard shortcut you want. Then everything else is handled internally and all you have to do is to implement the appropriate action that gets executed in the Click event handler of that menu entry.
You can even try this example:
public class MDIParent : System.Windows.Forms.Form
{
public bool NextTab()
{
// some code
}
public bool PreviousTab()
{
// some code
}
protected override bool ProcessCmdKey(ref Message message, Keys keys)
{
switch (keys)
{
case Keys.Control | Keys.Tab:
{
NextTab();
return true;
}
case Keys.Control | Keys.Shift | Keys.Tab:
{
PreviousTab();
return true;
}
}
return base.ProcessCmdKey(ref message, keys);
}
}
public class mySecondForm : System.Windows.Forms.Form
{
// some code...
}
If you have a menu then changing ShortcutKeys property of the ToolStripMenuItem should do the trick.
If not, you could create one and set its visible property to false.
From the main Form, you have to:
Be sure you set KeyPreview to true( TRUE by default)
Add MainForm_KeyDown(..) - by which you can set here any shortcuts you want.
Additionally,I have found this on google and I wanted to share this to those who are still searching for answers. (for global)
I think you have to be using user32.dll
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 0x0312)
{
/* Note that the three lines below are not needed if you only want to register one hotkey.
* The below lines are useful in case you want to register multiple keys, which you can use a switch with the id as argument, or if you want to know which key/modifier was pressed for some particular reason. */
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF); // The key of the hotkey that was pressed.
KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF); // The modifier of the hotkey that was pressed.
int id = m.WParam.ToInt32(); // The id of the hotkey that was pressed.
MessageBox.Show("Hotkey has been pressed!");
// do something
}
}
Further read this http://www.fluxbytes.com/csharp/how-to-register-a-global-hotkey-for-your-application-in-c/
Hans's answer could be made a little easier for someone new to this, so here is my version.
You do not need to fool with KeyPreview, leave it set to false. To use the code below, just paste it below your form1_load and run with F5 to see it work:
protected override void OnKeyPress(KeyPressEventArgs ex)
{
string xo = ex.KeyChar.ToString();
if (xo == "q") //You pressed "q" key on the keyboard
{
Form2 f2 = new Form2();
f2.Show();
}
}
In WinForm, we can always get the Control Key status by:
bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;
The VB.NET version of Hans' answer.
(There's a ProcessCmdKey function template in Visual Studio.)
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If (keyData = (Keys.Control Or Keys.F)) Then
' call your sub here, like
SearchDialog()
Return True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
End Class

how to take property value using droptarget?

I am creating a plugin and i need to know the value of porosity of reservoir. If these properties exist somewhere it would be much easier if I could just access them.
So how can we take these value using "drop target button" ?
You must subscribe to the DropTarget.DragDrop event. The following callback method shows you how to get the object dropped on the DropTarget button.
void DropTarget_DragDrop(object sender, DragEventArgs e)
{
Property property = e.Data.GetData(typeof(object)) as Property;
if (property == null)
return;
// Do something with property, like show it in a
// PresentationBox or store it for use later.
}

Number of Touchpoints in GestureRecognizer

I am using the GestureRecognizer to detect drag and pinch gestures.
The ManipulationStarted, ManipulationUpdated and ManipulationCompleted events provide the translation and scale values that are needed to pinch and drag.
However I cant figure out how to distinguish between drag (1 touch point) and pinch (2 touch points) gestures. There is no information about the number of touchpoints in GestureRecognizer.
How can I distinguish between drag and pinch with the GestureRecognizer?
Well, I feel it is very hacky (as most solutions seem to be for a useable WinRT app) but you can create a List<uint> to keep track of the number of pointers that are currently down on the screen. You would have to handle the PointerPressed event on whatever control you are interacting with (Let's say you are using a Canvas) to "capture" the pointers as they are pressed. That is where you would populate the List<uint>. Don't forget to clear the list at the end of the ManipulationCompleted event as well as any event that would fire upon the end of any gestures (like PointerReleased, PointerCanceled, and PointerCaptureLost). Maybe it would be a good idea to make sure the list is cleared in the ManipulationStarted event. Perhaps you can try that and see how that works for you.
In the ManipulationCompleted event, you can check if your List contains exactly 2 elements (PointerIds). If so, then you know it is a pinch/zoom.
Here is what it could look like:
private void Canvas_PointerPressed(object sender, PointerRoutedEventArgs e)
{
var ps = e.GetIntermediatePoints(null);
if (ps != null && ps.Count > 0)
{
this.gestureRecognizer.ProcessDownEvent(ps[0]);
this.pointerList.Add(e.Pointer.PointerId);
e.Handled = true;
}
}
private void gestureRecognizer_ManipulationCompleted(GestureRecognizer sender, ManipulationCompletedEventArgs args)
{
if (this.pointerList.Count == 2)
{
// This could be your pinch or zoom.
}
else
{
// This could be your drag.
}
// Don't forget to clear the list.
this.pointerList.Clear();
}
// Make sure you clear your list in whatever events make sense.
private void Canvas_PointerReleased(object sender, PointerRoutedEventArgs e)
{
this.pointerList.Clear();
}
private void Canvas_PointerCanceled(object sender, PointerRoutedEventArgs e)
{
this.pointerList.Clear();
}
I have been struggling with the same question for a few hours now and it looks WinRT platform does not provide that. What it instead provides is Delta.Rotation and Delta.Scale values in addition to Delta.Translation with the arguments to ManipulationUpdated callback.
If Delta.Rotation is 0 (or very close to zero - because it is a float value) and Delta.Scale is 1 (or very close to 1), you can conclude that a pinch operation is not the case and a drag operation is being carried otherwise it is a pinch operation. It is not the best you can get but it looks it is the only availability for the time being.

How to execute a binding for a metro control

I want to write the contents of a per occasion active TextBox back to the bound property of the ViewModel when the user presses the key combination for save (Ctrl-S).
My Problem with it is, that I'm not able to trigger the execution of the binding so that the bound Text-Property reflects the contents of the TextBox.
-There seems to be no GetBinding-method. Therefore I can not get the Binding and execute it manualy.
-There is no Validate-method such as in WinForms which executes the Binding
-Giving focus to another control from within KeyDown seems not to work, the binding does not execute
How can I achieve this?
Take a look at Aaron's discussion about this in his WiredPrarie blog post : http://www.wiredprairie.us/blog/index.php/archives/1701
I think I understand your question better now. One way around this would be to use a sub-classed textbox with a new property like this from here:
public class BindableTextBox : TextBox
{
public string BindableText
{
get { return (string)GetValue(BindableTextProperty); }
set { SetValue(BindableTextProperty, value); }
}
// Using a DependencyProperty as the backing store for BindableText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BindableTextProperty =
DependencyProperty.Register("BindableText", typeof(string), typeof(BindableTextBox), new PropertyMetadata("", OnBindableTextChanged));
private static void OnBindableTextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
{
((BindableTextBox)sender).OnBindableTextChanged((string)eventArgs.OldValue, (string)eventArgs.NewValue);
}
public BindableTextBox()
{
TextChanged += BindableTextBox_TextChanged;
}
private void OnBindableTextChanged(string oldValue, string newValue)
{
Text = newValue ? ? string.Empty; // null is not allowed as value!
}
private void BindableTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
BindableText = Text;
}
}
Then bind to the BindableText property.
Solution for command-instances
Here a solution I have found which is relatively leightweight, but also a bit "hackish":
btn.Focus(Windows.UI.Xaml.FocusState.Programmatic);
Dispatcher.ProcessEvent(CoreProcessEventsOption.ProcessAllIfPresent);
btn.Command.Execute(null);
First I give the focus to another control (In my case the button which has the bound command). Then I give the system time to execute the bindings and in the end I raise the command which is bound to the button.
Solution without bound commands
Give the Focus to another control and call the Dispatcher.ProcessEvent(...).
anotherControl.Focus(Windows.UI.Xaml.FocusState.Programmatic);
Dispatcher.ProcessEvent(CoreProcessEventsOption.ProcessAllIfPresent);
// Do your action here, the bound Text-property (or every other bound property) is now ready, binding has been executed
Please see also the solution of BStateham.
It's another way to solve the problem