After going through several articles and examples showing usage of
AdornedElementPlaceholder
i am still confused that what is the exact functionality it incorporates to xaml validation?
If you use Validations you need to show the user where (and what) failed to validated and that’s where AdornedElementPlaceholder comes into play. It is a Placeholder that has exactly the same size of the UIElement you’re validating.
Let’s say you’re validating user input on a TextBox and want to show a red box around the TextBox when the validation fails. Define a ValidationRule and a validation template for the TextBox. If the ValidationRule fails, then the Validation.ErrorTemplate is shown on your TextBox. Inside the template the AdornedElementPlaceholder tells the Framework where to place your template on the UI. In our case the template might look like this:
<ControlTemplate>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
You should read this article.
I believe the AdornedElementPlaceholder is used to show where the "validation indicator element" is positioned in relation to the control being validated.
I.e. if you have a text box and when validation fails a red x appears on the right of the box, I believe (although not 100%) that the AdornedElementPlaceholder is responsible for that positioning.
Represents the element used in a ControlTemplate to specify where a
decorated control is placed relative to other elements in the
ControlTemplate.
Source:
http://msdn.microsoft.com/en-us/library/system.windows.controls.adornedelementplaceholder(v=vs.110).aspx
Related
After going through several articles and examples showing usage of
AdornedElementPlaceholder
i am still confused that what is the exact functionality it incorporates to xaml validation?
If you use Validations you need to show the user where (and what) failed to validated and that’s where AdornedElementPlaceholder comes into play. It is a Placeholder that has exactly the same size of the UIElement you’re validating.
Let’s say you’re validating user input on a TextBox and want to show a red box around the TextBox when the validation fails. Define a ValidationRule and a validation template for the TextBox. If the ValidationRule fails, then the Validation.ErrorTemplate is shown on your TextBox. Inside the template the AdornedElementPlaceholder tells the Framework where to place your template on the UI. In our case the template might look like this:
<ControlTemplate>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
You should read this article.
I believe the AdornedElementPlaceholder is used to show where the "validation indicator element" is positioned in relation to the control being validated.
I.e. if you have a text box and when validation fails a red x appears on the right of the box, I believe (although not 100%) that the AdornedElementPlaceholder is responsible for that positioning.
Represents the element used in a ControlTemplate to specify where a
decorated control is placed relative to other elements in the
ControlTemplate.
Source:
http://msdn.microsoft.com/en-us/library/system.windows.controls.adornedelementplaceholder(v=vs.110).aspx
I'm getting there with this WPF validation, IDataErrorInfo, INotifyPropertyChange stuff, but new issue on refresh. I have a window with a bunch of controls on it. I have a tabbed page interface and for simplicity have 2 pages... 5 controls on each.
I start to "Add" a record, so all fields are blank. Ex: 3 of the fields on the first page that require validation are properly flagged as red border to indicate they are required... no problem.
Now, I click on to page 2 and immediately back to page 1. The red borders are all gone. They don't reappear red unless I explicitly tab through them to re-focus them, lose focus and force it to do its lostfocus / property changed validation via IDataErrorInfo.
First, any explanation WHY WPF is losing what the first page looks like just because it has to change page 1's visiblity to show page 2, and then back to page 1.
Second, suggestions on how to force the controls to be properly refreshed with the red border indicating they are required.
Thanks
Just put the controls you validate inside an AdornerDecorator an it will work fine ;)
<TabItem>
<AdornerDecorator>
<Grid>
<TextBox>
</TextBox>
...
</Grid>
</AdornerDecorator>
</TabItem>
If I recall correctly, the default error validation markers for controls are just red boxes overlaid over the top of the control, not part of the control itself, so the visibility of that overlay does not persist if the control is hidden. You might try changing the control template to incorporate a red border / label directly as part of the control, and that issue might be cleared up.
To force all your bindings to refresh (and therefore their validation) all you need to do is call RaisePropertyChanged again for any property you want to re-validate. It's a little wasteful, but you can just call RaisePropertyChanged with an empty string as parameter, and it will raise for all properties in the viewmodel.
we often see any ajax based website where textbox is placed for searching data. when we write something in the textbox and when data is fetching then a spinner gif images is shown in the textbox with right align. i know this done via css. so how can i achieve the same effect in wpf where textbox will be there and user will write something in the textbox and when data will be fetch then a spinning gif image will show in the textbox with right align and when data fetch will be completed then image will be invisible. please guide me with sample code if possible. thanks
To get you started, look at Data Validation in WPF, specifically, look for the section on Providing Visual Feedback with the AdornedElementPlaceHolder class in WPF.
<AdornedElementPlaceholder/>
It is my belief that this mechanism could be relatively easily adapted to solving your particular problem.
Edit: Additional info
In your case, you'll create a control template for a TextBox and assign that control template to your textbox element. This example varies from the example in the link by changing the TextBox to an Image element. The TextBox in the example in the link is the red character that represents some sort of validation error.
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<Image Source="<location of your animated gif>">
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>
FindAncestor RelativeSource only supports 'Self' and 'TemplatedParent',
but I have to bind the width of a popup to the width of the page.
Giving the page a name causes problems because sometimes it will
throw exceptions saying a control with that name is already present in the visual tree.
<Popup IsOpen="True"
Width="{Binding ElementName=BordPage, Path=Width}"
Height="{Binding ElementName=BordPage, Path=Height}">
Background information:
I'm using a SL4 navigation based application here. BordPage is a navigation page,
which I'm using multiple times within the application. So giving it a name in the page itself is not really a good idea,
but I don't know how else I can bind to the width and height of the page.
What I'm trying to do is have a black border (with opacity 0.8) cover the entire screen,
(including the controls of the MainPage). Then on top of that I want to display some other controls.
Since the application is touch controlled, providing the user with a ComboBox to select a value doesn't really work wel. Instead I want to show this black overlay window with a listbox taking up most of the screen so the user can simply touch the value he wants with a single click.
Update: I just realized I can use the ChildWindow class to do this.
But my original question remains.
My general solution for this problem is by writing a custom behavior. It's not a pure XAML solution but it gives you a lot more flexibility.
Create a behavior that searches up the VisualTree to find the right item and then have it set the width of the Popup correctly.
It may be a little more complicated than a straight binding but it avoids all the naming issues.
Put the following in the constructor of your control so you can avoid naming it:
DataContext = this;
I am extending the WPF textbox in order to place a custom image on it. I want to capture mouse clicks on this image. So far i have been able to use arrangeOverride to place the image in where i need it but since it happens to be placed "inside" the text box, whenever i try clicking it the text box captures the click and the event that is attached to the image does not fire. Is it possible to indicate that the image should be placed on top of the text box when using arrange override? I know i can get around this issue if i extended a Control and placed a text box inside it, but for my application i need to actually extend a text box in order to be able to use it in another more complex control that is currently using a text box.
Thanks!
ArrangeOverride may not be the ideal solution for this. A better approach would probably be to use control templating: create a ControlTemplate containing a Grid with a single cell, and place the Image and the text box content host in that single cell. You can place the Image on top implicitly by the order you place the controls, or explicitly by setting the Panel.ZIndex attached property.
The one trick here is knowing how to represent the text box content host. This has to be a ScrollViewer with the name PART_ContentHost. So your template will look something like:
<ControlTemplate TargetType="{x:Type Ambog36sTextBox}">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" /> <!-- WPF will fill in a text edit area here -->
<Image Panel.ZIndex="1" Source="..." />
</Grid>
</ControlTemplate>
Then assign this template to your custom text box class via the default style in the usual way.
As you are not using the standard composition model it means you need to override the mouse handling before it reaches the text box code and add your own custom logic to decide on the events to generate.