Hello,
I have a TabControl with a series of User Controls in each tab. I am investigating using the PreviewSelectionChanged event to stop a tab change if a tab does not pass some validation. I am basing my ideas off of this code below:
But insead of checking a built in property of the RadTabItem, I want to run a function in my user control, likely an IsValid() function returning a bool to decide whether to cancel the tab switch or not. I am using the MVVM pattern in the UserControls if that makes a difference, but I don't mind running the validation in the UserControl itself if that is the way to do it.
Thanks.
I have a TabControl with a series of User Controls in each tab. I am investigating using the PreviewSelectionChanged event to stop a tab change if a tab does not pass some validation. I am basing my ideas off of this code below:
private void TabControl_PreviewSelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e) |
{ |
RadTabItem navTo = e.AddedItems[0] as RadTabItem; |
if (navTo.Visibility == Visibility.Collapsed) |
{ |
e.Handled = true; |
} |
} |
But insead of checking a built in property of the RadTabItem, I want to run a function in my user control, likely an IsValid() function returning a bool to decide whether to cancel the tab switch or not. I am using the MVVM pattern in the UserControls if that makes a difference, but I don't mind running the validation in the UserControl itself if that is the way to do it.
Thanks.
6 Answers, 1 is accepted
0
Hello Sean,
The example attached shows how to handle the PreviewSelected event based on a condition coming from the ViewModel. The ViewModel in the attached project is a class called DataItem and it contains one public property called IsValid. On PreviewSelected, if the item in e.AddedItems[0] has its property IsValid set to true, we do not handle the preview event. Otherwise we handle it.
Another way to look at this scenario is if you have specified your tab items in xaml.
Then in the PreviewSelected event handler, you will receive the tab item and the user control will be its content.
I am not sure which one is your scenario, so if you find it difficult to continue after these explanations, let us know which is you scenario and we will be glad to further assist you.
Best wishes,
Viktor Tsvetkov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
The example attached shows how to handle the PreviewSelected event based on a condition coming from the ViewModel. The ViewModel in the attached project is a class called DataItem and it contains one public property called IsValid. On PreviewSelected, if the item in e.AddedItems[0] has its property IsValid set to true, we do not handle the preview event. Otherwise we handle it.
public
partial
class
MainPage : UserControl
{
public
MainPage()
{
InitializeComponent();
ObservableCollection<DataItem> items =
new
ObservableCollection<DataItem>();
items.Add(
new
DataItem(
"First"
,
true
));
items.Add(
new
DataItem(
"Second"
,
false
));
items.Add(
new
DataItem(
"Third"
,
true
));
tabControl.ItemsSource = items;
}
private
void
tabControl_PreviewSelectionChanged(
object
sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
{
var tabItem = e.AddedItems[0]
as
DataItem;
if
(!tabItem.IsValid)
{
e.Handled =
true
;
}
}
}
public
class
DataItem
{
public
DataItem(
string
name,
bool
isValid)
{
this
.Name = name;
this
.IsValid = isValid;
}
public
string
Name {
get
;
set
; }
public
bool
IsValid {
get
;
set
; }
}
Another way to look at this scenario is if you have specified your tab items in xaml.
<
telerikNavigation:RadTabControl
x:Name
=
"tabControl"
PreviewSelectionChanged
=
"tabControl_PreviewSelectionChanged"
>
<
telerikNavigation:RadTabItem
Header
=
"Item 0"
>
<
myUserControls:UserControl_0
/>
</
telerikNavigation:RadTabItem
>
<
telerikNavigation:RadTabItem
Header
=
"Item 1"
>
<
myUserControls:UserControl_1
/>
</
telerikNavigation:RadTabItem
>
<
telerikNavigation:RadTabItem
Header
=
"Item 2"
>
<
myUserControls:UserControl_2
/>
</
telerikNavigation:RadTabItem
>
</
telerikNavigation:RadTabControl
>
Then in the PreviewSelected event handler, you will receive the tab item and the user control will be its content.
private
void
tabControl_PreviewSelectionChanged(
object
sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
{
var tabItem = e.AddedItems[0]
as
RadTabItem;
if
(tabItem !=
null
)
{
MyUserControl myUserControl = tabItem.Content
as
MyUserControl;
if
(myUserControl !=
null
)
{
// ValidationFunction is your function that will execute the logic for determining whether to handle the preview event or not
if
(myUserControl.ValidationFunction() ==
true
)
{
e.Handled =
false
;
}
else
{
e.Handled =
true
;
}
}
}
}
I am not sure which one is your scenario, so if you find it difficult to continue after these explanations, let us know which is you scenario and we will be glad to further assist you.
Best wishes,
Viktor Tsvetkov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Sean
Top achievements
Rank 1
answered on 21 Jun 2010, 07:13 PM
Thanks for your response.
The approach I took was to get each tab to derive off of a common interface. The interface has a bool IsValid() function (among others).
Once I cast the navFrom tab into the interface type I can get access to the IsValid function. Each tab then implements it's own version of the IsValid function.
Thanks for pointing me in the right direction!
The approach I took was to get each tab to derive off of a common interface. The interface has a bool IsValid() function (among others).
Once I cast the navFrom tab into the interface type I can get access to the IsValid function. Each tab then implements it's own version of the IsValid function.
interface IUITab |
{ |
bool IsValid(); |
void RefreshView(); |
void Save(); |
} |
IUITab currentTab = navFrom.Content as IUITab; |
if (currentTab != null && currentTab.IsValid() == false) |
e.Handled = true; |
Thanks for pointing me in the right direction!
0
codeputer
Top achievements
Rank 2
answered on 02 Mar 2011, 01:46 AM
I'm in the same scenario, wanting to validate my view model before allowing a tab switch. However, if I make a change in a (say) textbox, then use the mouse to click the next tab - the tab switch occurs before the textbox control flushes to the viewmodel!
Hence when I validate the model, it does not see the change yet!
I realize that this is not the tab controls problem - but I'm looking for help to flush the bindings before the preview selection event?
Shouldn't the control flush the binding when it loses focus? Why does a mouse move from the field not cause a binding to flush?
Richard
Hence when I validate the model, it does not see the change yet!
I realize that this is not the tab controls problem - but I'm looking for help to flush the bindings before the preview selection event?
Shouldn't the control flush the binding when it loses focus? Why does a mouse move from the field not cause a binding to flush?
Richard
0
Hi codputer,
I prepared a sample for you that shows how to update the binding in the TextChanged event handler of the TextBox. Basically it sets Explicit UpdateSourceTrigger like so:
Then In code behind you have to update the source like so:
The described apporach is realized in the attached solution. So please gibe it a try and let us know if it satisfies you.
Best wishes,
Petar Mladenov
the Telerik team
I prepared a sample for you that shows how to update the binding in the TextChanged event handler of the TextBox. Basically it sets Explicit UpdateSourceTrigger like so:
<
telerik:RadTabControl.ContentTemplate
>
<
DataTemplate
>
<
TextBox
Width
=
"200"
Height
=
"40"
VerticalAlignment
=
"Center"
Text
=
"{Binding Description, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
TextChanged
=
"TextBox_TextChanged"
/>
</
DataTemplate
>
</
telerik:RadTabControl.ContentTemplate
>
private
void
TextBox_TextChanged(
object
sender, TextChangedEventArgs e)
{
TextBox textBox = sender
as
TextBox;
BindingExpression binding = textBox.GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
Best wishes,
Petar Mladenov
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
codeputer
Top achievements
Rank 2
answered on 04 Mar 2011, 06:00 PM
Hello! Thanks for the quick reply.
I'm familiar with this but i would hate to have to implement this on all my text box controls. Another fix is to flush the binding on each keystroke, hence getting the update before leaving the control. Can you confirm if Telerik's textbox control does this? Perhaps I should just only use telerik controls? :)
I had a simliar in WinForms, the fix was to also flush the binding, but I could do it centrally via the binding source.
I was amazed however that this well documented problem still exists in the framework. If you leave a control via a mouse move, it simply cannot "react" fast enough in order to get the messages dispatched in the correct timeline order.
I've put up a discussion on StackOverFlow - but had to find anybody to discuss in detail as very few developers know what the message pump is anymore.
R
I'm familiar with this but i would hate to have to implement this on all my text box controls. Another fix is to flush the binding on each keystroke, hence getting the update before leaving the control. Can you confirm if Telerik's textbox control does this? Perhaps I should just only use telerik controls? :)
I had a simliar in WinForms, the fix was to also flush the binding, but I could do it centrally via the binding source.
I was amazed however that this well documented problem still exists in the framework. If you leave a control via a mouse move, it simply cannot "react" fast enough in order to get the messages dispatched in the correct timeline order.
I've put up a discussion on StackOverFlow - but had to find anybody to discuss in detail as very few developers know what the message pump is anymore.
R
0
Hi codputer,
You can use our new MaskedInput controls available from Q1 2001 Beta. Check out this help article that describes how to use the validation feature and the corresponding demo. Hope this can fit in your scenario.
Kind regards,
Petar Mladenov
the Telerik team
You can use our new MaskedInput controls available from Q1 2001 Beta. Check out this help article that describes how to use the validation feature and the corresponding demo. Hope this can fit in your scenario.
Kind regards,
Petar Mladenov
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!