|
You just need to modify the control template and add a MouseOver trigger the same as you would any other control. If they don't give you the XAML templates, you can dump them out with Blend.
|
|
|
|
|
OK - and I though this one was going to be easy!
I want a text box in a WPF form into which the user can enter a currency amount (e.g. $12.34)
I want to be able to give them an error message if they type in rubbish (e.g. "freds cash")
I want to be able to validate for ranges (so they can't for example, enter -ve numbers )
My 1st thought was to bind a standard textbox to my data property, which is a Decimal?, which doesn't work very well, as if the user types rubbish, an exception is thrown which (as far as I can ascertain) I can't catch!) I know I can display an error message/highlight the control if this happens, but this means that what is shown on the screen doesn't match what is in the property that I'm binding to - so what happens if the user now clicks the SAVE button? it saves the 'old' value, not what's on the screen, that's what!
Solutions I have seen include only binding to strings, and then validating the user input in the setter of those strings. Josh Smith does this here[^] While I like this idea, I feel a little uncomfortable - I'd really like to bind to the 'real' data and not a string representation of it.
Other solutions I came across included karl's solution here[^] which looks very interesting.
But I figure, WPF has been around for a while, so surely there's some accepted way of entering monetary amounts?
Am I missing something really obvious, so obvious that nobody's blogging about it? Or, am I just crap at Googling? Or, do I need to look at Josh or Karl's solution and use one of them? Or, is there a better way?
|
|
|
|
|
You need an attached behavior for this. I wrote one for Goldlight that effectively looks like this:
namespace Goldlight.Behaviors
{
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Input;
using System.Windows.Controls;
using System.Text.RegularExpressions;
public class NumericTextBoxBehavior : Behavior<TextBox>
{
#region Overrides
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.PreviewTextInput += AssociatedObject_PreviewTextInput;
DataObject.AddPastingHandler(AssociatedObject, OnClipboardPaste);
}
protected override void OnDetaching()
{
AssociatedObject.PreviewTextInput -= AssociatedObject_PreviewTextInput;
DataObject.RemovePastingHandler(AssociatedObject, OnClipboardPaste);
}
#endregion
#region Private Methods
private void AssociatedObject_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
var tb = AssociatedObject;
e.Handled = !Validate(e.Text);
}
private void OnClipboardPaste(object sender, DataObjectPastingEventArgs e)
{
var tb = sender as TextBox;
string text = e.SourceDataObject.GetData(e.FormatToApply) as string;
if (!string.IsNullOrEmpty(text) && !Validate(text))
{
e.CancelCommand();
}
}
private bool Validate(string newContent)
{
TextBox tb = AssociatedObject;
string testString = string.Empty;
string pre = string.Empty;
string post = string.Empty;
if (!string.IsNullOrEmpty(tb.SelectedText))
{
pre = tb.Text.Substring(0, tb.SelectionStart);
post = tb.Text.Substring(tb.SelectionStart + tb.SelectionLength,
tb.Text.Length - (tb.SelectionStart + tb.SelectionLength));
}
else
{
pre = tb.Text.Substring(0, tb.CaretIndex);
post = tb.Text.Substring(tb.CaretIndex, tb.Text.Length - tb.CaretIndex);
}
testString = pre + newContent + post;
Regex regExpr = new Regex(@"^([-+]?)(\d*)([,.]?)(\d*)$");
return (regExpr.IsMatch(testString));
}
#endregion
}
} The full Goldlight version does quite a bit more with the regex, but this basic logic holds. Now, all you need to do is attach this to your TextBox .
|
|
|
|
|
Right, the way I've implemented this in Goldlight is shown in this blog entry[^].
I'm not a stalker, I just know things. Oh by the way, you're out of milk. Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Onyx
modified on Wednesday, March 30, 2011 3:40 PM
|
|
|
|
|
I don't quite know how to reply without sounding as if I have a man-crush on you.
Just looking at the string.Format pattern made my eyes look like those of the snake in The Jungle Book movie!
Thanks!
|
|
|
|
|
No problem. Glad I can help.
|
|
|
|
|
I have a Gridview where i bind the list of values from my model. Now i have a bit field from the DB and it represents yes or no, or true or false using 1 and 0. Now i want to bind this to a Checkbox column and below is what i have
<telerik:GridViewCheckBoxColumn AutoSelectOnEdit="True" DataMemberBinding="{Binding sIsMain,Mode=TwoWay}"></telerik:GridViewCheckBoxColumn>
and it give me an Error when i run it.
SCRIPT5022: Unhandled Error in Silverlight Application
Code: 4004
Category: ManagedRuntimeError
Message: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.ThrowHelper.ThrowKeyNotFoundException()
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at System.Windows.ResourceManagerWrapper.GetResourceForUri(Uri xamlUri, Type componentType)
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vuyiswamaseko.com
vuyiswa@its.co.za
http://www.itsabacus.co.za/itsabacus/
modified on Wednesday, March 30, 2011 4:18 AM
|
|
|
|
|
The problem's not quite the one you think it is. Basically the exception is telling you that the resource wrapper failed to get resource styling at System.Windows.ResourceManagerWrapper.GetResourceForUri(Uri xamlUri, Type componentType). The reason for this is unrelated to styling altogether. Basically, you are using a byte to represent a boolean condition, so I'd look at either converting the value to a boolean beforehand or converting the byte with a value converter:
namespace MyConverters
{
using System;
using System.Windows.Data;
public class ByteToBooleanConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
byte conv = (byte)value;
return conv == (byte)1;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
}
|
|
|
|
|
Thank you for your reply. i have converted the Model to give me a Boolean , but the Database is kept untouched and its working fine.
Thanks
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vuyiswamaseko.com
vuyiswa@its.co.za
http://www.itsabacus.co.za/itsabacus/
|
|
|
|
|
Good job
|
|
|
|
|
I check on the Internet - and i actually try anything i found ... and still nothing work.
I have simple server that i wrote using WCF ( .net 4.0 ) and simple silverlight ( .net 4.0 ) application that use this WCF service.
Both of them are on the same sulotion.
I want to use the IIS ( 7.5 ) - so in compiling i define the visual studio to 'use local IIS web server'.
Now, when i testing my silverlight apps on debug - i see that all work fine ( the WCF service call work fine ).
But when i ran it directly from the explorer i see that i get message about that the silverlight app. can't call the WCF service.
( cross-domain problem )
The exception error is:
An error occurred while trying to make a request to URI ‘http://localhost/MyService’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. Please see the inner exception for more details.
I try to add clientaccesspolicy.xml and crossdomain.xml file to the WCF folder ( the folder that contain the .cvs file )
I try to add clientaccesspolicy.xml and crossdomain.xml file to the WCF folder that contain the interface contract files.
But still nothing work.
I still get the same exception message.
Is there some code example to see how to do it right ?
|
|
|
|
|
You need to locate the clientaccesspolicy.xml file in the root of the domain that you intend to serve the data from. So, if you were hosting it as http://localhost/MyApplication/MyService.xml, the policy would be http://localhost/clientaccesspolicy.xml and not http://localhost/MyApplication/clientaccesspolicy.xml.
Note: Similar logic applies to the crossdomain.xml file.
|
|
|
|
|
I can access to http://localhost/clientaccesspolicy.xml
The clientaccesspolicy.xml is
<br />
<br />
<?xml version="1.0" encoding="utf-8" ?> <br />
- <access-policy><br />
- <cross-domain-access><br />
- <policy><br />
- <allow-from http-request-headers="*"><br />
<domain uri="*" /> <br />
</allow-from><br />
- <grant-to><br />
<resource path="/" include-subpaths="true" /> <br />
</grant-to><br />
</policy><br />
</cross-domain-access><br />
</access-policy><br />
<br />
and still nothing help.
|
|
|
|
|
What about your crossdomain.xml? What happens if you browse to http://localhost/crossdomain.xml?
|
|
|
|
|
I can see the crossdomain.xml also when i try to enter
http://A.B.C.D/crossdomain.xml
from explorer - from different machine ( A.B.C.D is the server machine IP )
|
|
|
|
|
The first thought I have is that perhaps SOAPAction has been blacklisted. In the section
<allow-from http-request-headers="*"> change this to <allow-from http-request-headers="SOAPAction"> instead.
|
|
|
|
|
Hi,
There are two usercontrols i.e. page1.xaml, page2.xaml in my silverlight project which I am using like pages.
There are alot of codes in each usercontrol...
I would like to have one main page with a tab control and tab1 to show page1 and tab2 to show page2.
Is this possible?
Is it just a matter of referencing each control from each tab in the tab control?
Thank you
|
|
|
|
|
yes, this is possible.
you will have ( in the simple way ) reference to the tab control.
[I'm not sure but i think you can access to the usercontrol by calling too tabControl.Items - but any time you can use events to communicate with the userControl.
|
|
|
|
|
arkiboys wrote: would like to have one main page
This is exactly how we have designed our apps, you need to implement the navigation frame.
<Navigation:Frame x:Name="MainContent" Grid.Column="1" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
Source="Home" UriMapper="{StaticResource MyMapper}">
Our pages are usercontrols (this change is minimal) and we set the source have on user selections
Look into xmlns:Navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
This is what I am trying to do now.
My main page has the navigation frame with the navigation menue on the left hand side.
Clicking each linkbutton in the menue will navigate to the desired page and show the page inside the mainframe.
Question:
In page2.xaml, I have placed a button, and wouold like it to navigate me to the page1.xaml when clicked.
So, in page2.xaml, I have placed the namespace for navigation and the following code in the button
private void btnNavigate_Click(object sender, RoutedEventArgs e)
{
mainFrame.Navigate(new Uri("/Page1.xaml", UriKind.Relative));
}
BUT the problem is that mainFrame is on the mainpage.xaml and not on page2.xaml, so I get an error when running the application.
Does this mean I have to copy the mainframe xaml to the page2.xaml as well?
Thanks
|
|
|
|
|
I have a static class that handles the navigation.
public static class MainUI
{
public static void NavigateTo(string sViewName)
{
Frame oFR = (Application.Current.RootVisual as FrameworkElement).FindName("MainContent") as Frame;
NavigateTo(oFR,sViewName);
}
public static void NavigateTo(Frame oFR, string sViewName)
{
oFR.Navigate(new Uri(sViewName, UriKind.Relative));
}
The default is to use the main page navigate frame but I also use navigate frames within other pages.
private void ControlNavigate(object sender, RoutedEventArgs e)
{
Frame oFrame = this.FilterContent;
string sURL = "Blank";
switch ((sender as HyperlinkButton).Content.ToString())
{
case "Accounts":
sURL = "AccountFilter";
break;
case "Elements":
sURL = "ElementNodeFilter";
break;
case "Products":
sURL = "ProductFilter";
break;
}
gUI.NavigateTo(oFrame, sURL);
}
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Hi,
Thanks for the reply...
In my silverlight application, my main page is called HomePage.xaml which is a user control.
1- In regards to your second code which is ControlNavigate, does this have to be placed inside a navigated page or a usercontrol?, it's just that if I place it inside my page2.xaml, the compiler underlines an error for:
this.FilterContent and gUI
2-There is a Login.xaml which is a usercontrol. From page2.xaml I can now navigate to login.xaml using the code you sent.
BUT, using the button in login.xaml, I am unable to navigate to another page. When debugging, it seems your code for navigatioin does not give any error but it goes into Application_UnhandledException inside app.xaml.cs
Any thoughts on the above point please?
Thanks
modified on Thursday, March 31, 2011 12:50 AM
|
|
|
|
|
Good Evening
I have a Datagrid and i selectedChange event of the Datagrid, i show a child wind and i bind the textbox controls of the child window from the Parent Window which has a datagrid. Now my problem is that there is a Combobox on the Child window, onbviously this combobox is binded after the child window has opened. The data is not Static , its coming from the DB. What i want is to set the selected item from the parent. This is what i am doing
private void grdkids_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangeEventArgs e)
{
KidsViewUpdateDetails KidsDetails = new KidsViewUpdateDetails();
KidsModelExtended model = (KidsModelExtended)this.grdkids.SelectedItem;
KidsDetails.txtstudentnumber.Text = model.sStudentNumber;
KidsDetails.txtkidname.Text = model.sKidName;
KidsDetails.txtkidlastname.Text = model.sKidLastname;
KidsDetails.txtgrade.Text = model.sKidGrade;
KidsDetails.txtclass.Text = model.skidclass;
KidsDetails.ddlallergies.Text = model.sAllergyName;
KidsDetails.ddlschool.Text = model.sSchoolName;
GenericMethods.GenericMethods.SetCookie("kidId", model.iKidid.ToString());
KidsDetails.Show();
}
in this lines
KidsDetails.ddlallergies.Text = model.sAllergyName;
KidsDetails.ddlschool.Text = model.sSchoolName;
i am trying set the selected item to be that. but when the Child load , there Combobox remain unselected
This is the declaration of the Combobox
<telerik:RadComboBox HorizontalAlignment="Left" DisplayMemberPath="sAllergyName" SelectedValuePath="{Binding iAllergyID}" Margin="106,226,0,0" Name="ddlallergies" VerticalAlignment="Top" Width="142" Height="22">
Thanks
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vuyiswamaseko.com
vuyiswa@its.co.za
http://www.itsabacus.co.za/itsabacus/
|
|
|
|
|
I have found the combobox the most irritating control in SL, if any of the underlying data objects is changed, the combos binding is negated. I have a BindCombo() in the code behind. This renews the binding after the page has loaded and if any of the data sources change state (.Clear(), or new on the observablecollection that serve the itemssource and the selecteditem).
If the binding is setup properly then changing the selecteditem in the datasource of the datagrid should automatically update the combobox selected item.
You need to get away from manipulating the UI elements, its so... winforms.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I must agree , it is really annoying. This is supposed to be a simple thing.
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vuyiswamaseko.com
vuyiswa@its.co.za
http://www.itsabacus.co.za/itsabacus/
|
|
|
|
|