My question is fairly simple, because it works in other cases but not with double click mouse event. I want to make editable tab items, and its almost done. Maybe code will clear the situation:
<StackPanel Orientation="Horizontal">
<TextBox x:Name="HeaderEditMode" Text="{Binding Header, Mode=TwoWay}" Visibility="Collapsed" />
<TextBlock x:Name="HeaderDisplayMode" Text="{Binding Header, Mode=TwoWay}" />
<StackPanel.Triggers>
<EventTrigger RoutedEvent="MouseDoubleClick">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderEditMode"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderDisplayMode"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderEditMode"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderDisplayMode"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
</StackPanel>
If you change MouseDoubleClick to for example to MouseDown or MouseEnter it works perfectly. Any suggestions?
Try wrapping your TextBlock in a ContentControl, and attach the MouseDoubleClick trigger to that instead.
Related
I have TabView that basically looks like this:
<controls:TabView
x:Name="PlaylistTabView">
<controls:TabView.ItemHeaderTemplate>
<DataTemplate x:DataType="data:Playlist">
// Something
</DataTemplate>
</controls:TabView.ItemHeaderTemplate>
<controls:TabView.ItemTemplate>
<DataTemplate x:DataType="data:Playlist">
<local:HeaderedPlaylistControl IsPlaylist="True" Loaded="HeaderedPlaylistControl_Loaded" />
</DataTemplate>
</controls:TabView.ItemTemplate>
<controls:TabView.TabStartHeader>
// Something
</controls:TabView.TabStartHeader>
<controls:TabView.TabEndHeader>
// Something
</controls:TabView.TabEndHeader>
<controls:TabView.Footer>
<RelativePanel
x:Name="PlaylistFooter"
Height="{StaticResource PlaylistTabFooterHeight}"
RenderTransformOrigin="0,0">
<RelativePanel.RenderTransform>
<TranslateTransform />
</RelativePanel.RenderTransform>
<local:IconTextButton
x:Name="ShowAllPlaylistButton"
Padding="10,5"
IconTextMargin="0,0,10,0"
LabelPosition="Left"
RelativePanel.AlignRightWithPanel="True"
Style="{StaticResource PlaylistIconTextButtonStyle}"
ToolTipService.ToolTip="Show All Playlists">
<local:IconTextButton.Icon>
<FontIcon
x:Name="UpArrowIcon"
FontFamily="Segoe MDL2 Assets"
FontWeight="{x:Bind ShowAllPlaylistButton.FontWeight}"
Glyph=""
RenderTransformOrigin=".5,.5">
<FontIcon.RenderTransform>
<RotateTransform />
</FontIcon.RenderTransform>
</FontIcon>
</local:IconTextButton.Icon>
<local:IconTextButton.Flyout>
<MenuFlyout Closed="ClosePlaylistsFlyout" Opening="OpenPlaylistsFlyout" />
</local:IconTextButton.Flyout>
</local:IconTextButton>
<local:IconTextButton
x:Name="SortByButton"
Padding="10,5"
HorizontalAlignment="Right"
Icon="Sort"
IconTextMargin="10,0,0,0"
Label="Sort By Title"
LabelPosition="Right"
RelativePanel.AlignLeftWithPanel="True"
Style="{StaticResource PlaylistIconTextButtonStyle}"
Tapped="SortByButton_Tapped"
ToolTipService.ToolTip="Sort Playlists" />
</RelativePanel>
</controls:TabView.Footer>
</controls:TabView>
I have a local:HeaderedPlaylistControl in the ItemTemplate which is basically a ListView. I want to implement the effect that as you scroll down the footer will translate down and when you scroll up the footer will quickly show up.
I am able to implement such effect. However, I am only moving the PlaylistFooter not the TabView.Footer, meaning that the Footer lingers and leaves a blank space at the bottom as is shown in the picture below. How can I move the footer as well?
I checked your code, I found you have implemented TranslateTransform for PlaylistFooter, if you just move the PlaylistFooter down not set Visibility as Collapsed, the footer will still display, So the better way is set Visibility as Collapsed.
<VisualStateGroup x:Name="FooterVisibilityStates">
<VisualState x:Name="FooterFadeIn">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PlaylistFooter" Storyboard.TargetProperty="Opacity">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaylistFooter" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="Visibility" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="FooterFadeOut">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PlaylistFooter" Storyboard.TargetProperty="Opacity">
<EasingDoubleKeyFrame KeyTime="0" Value="1" />
<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0" />
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaylistFooter" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.4" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaylistFooter" Storyboard.TargetProperty="IsHitTestVisible">
<DiscreteObjectKeyFrame KeyTime="0" Value="False" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
Update
After discuss with Seaky Luo, we found a solution that set PlaylistFooter height as 0 when the list view scroll down. For more please refer the following code.
<Storyboard x:Name="HideFooterAnimation">
<DoubleAnimation
Storyboard.TargetName="PlaylistFooter"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
To="0"
Duration="0:0:0.1" />
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="PlaylistFooter"
Storyboard.TargetProperty="Height"
Duration="0:0:0.1">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PlaylistTabFooterHeight}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="ShowFooterAnimation">
<DoubleAnimation
Storyboard.TargetName="PlaylistFooter"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
To="{StaticResource PlaylistTabFooterHeight}"
Duration="0" />
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="PlaylistFooter"
Storyboard.TargetProperty="Height"
Duration="0">
<DiscreteObjectKeyFrame KeyTime="0" Value="0" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
How to display a blinking notification message over parts of the main window of an application, while keeping the controls below of the overlay reachable (clickable) if the overlay is turned off?
The easy part is to create the overlay and build a storyboard for the animation:
<Window.Resources>
<Style x:Key="ds_NotificationStyle" TargetType="DockPanel">
<Setter Property="Opacity" Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding EnableNotification}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="ds_BeginCallNotification">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0.4" Duration="0:0:0.4" AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="ds_BeginCallNotification" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
Further below in the XAML, the overlay elements (there is a grid populated with other elements and the following DockPanel is placed above of them):
<DockPanel Grid.RowSpan="2" Name="ds_NotificationPanel" Style="{StaticResource ds_NotificationStyle}" Panel.ZIndex="200" Background="AntiqueWhite" Height="100" VerticalAlignment="top">
<Viewbox>
<TextBlock Text="{Binding IncomingCallNotification}" Margin="5" Foreground="Brown" FontWeight="Bold" />
</Viewbox>
</DockPanel>
But there is a problem now with the overlay, blocking all the controls underneath of it.
To solve this, the DockPanel's visibility has to be set to Collapsed. But how to adjust this visibility before and after the animation?
Toggle the visibility at the beginning, using an animation that targets runtime zero of the storyboard:
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
But at the same location, I had no idea how to reset the visibility back to Collapsed.
Using another Storyboard that is run at the ExitActions trigger solved this issue:
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
Here is the complete solution (the DockPanel elements arent' changed):
<Window.Resources>
<Style x:Key="ds_NotificationStyle" TargetType="DockPanel">
<Setter Property="Opacity" Value="0" />
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding EnableNotification}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="ds_BeginCallNotification">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0.4" Duration="0:0:0.4" AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="ds_BeginCallNotification" />
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="00:00:00.2" />
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
This may be easy and obvious for many of you, but it took me some times to figure it out. As I would have been grateful for such an answer, I have posted my solution here.
I have next triggers in my XAML:
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsOpened}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="Control"
Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)">
<LinearDoubleKeyFrame KeyTime="0:0:0.30" Value="-310"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="OpenHelpText" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.30"
Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="CloseHelpText" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.30"
Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="ClosePanel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.30"
Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="OpenPanel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.30"
Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="Control"
Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)">
<LinearDoubleKeyFrame KeyTime="0:0:0.30" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="CloseHelpText" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.30"
Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="OpenHelpText" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.30"
Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="ClosePanel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.30"
Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="OpenPanel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.30"
Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</ControlTemplate.Triggers>
And I have some dynamic parameter that tells whether the animation be enabled, or not.
(Dynamic - means that animation should be enabled/disabled whenever parameter value changes)
What is the best way to disable/enable animation?
UPD: As an alternative - is that possible to create the same animation in code?
Refer this link like dis....
Bind Element name to main property.Here i used Toggleswitch element name i bind with button
Visibility="{Binding IsOn,ElementName=togglebutton}, Converter={StaticResource BooleanToVisibilityConverter}}" />
Update the trigger criteria on your DataTrigger.
You are embedding the animations in your DataTriggers already.
In your case, perhaps you can leverage MultiDataTriggers to account for multiple conditions that must be met.
Im not sure why the following is not working. I am attempting hiding and showing a textbox every .2 seconds for 1.2 seconds when the bound model property changes. can anyone see an issue with this style or how i am attempting to do this?
<Style x:Key="FlashStyle" TargetType="TextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated" >
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00.2" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.4" Value="{x:Static Visibility.Collapsed}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.6" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.8" Value="{x:Static Visibility.Collapsed}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:01" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
<TextBlock Text="{Binding Data.QuotePrice, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource FlashStyle}" />
The Binding.TargetUpdated event does not occur:
Occurs when a value is transferred from the binding source to the binding target, but only for bindings with the NotifyOnTargetUpdated value set to true.
Only thing i can think of besides precedence (which should be fine if this is your actual code).
I'm trying to plan an mvvm based infrastructure, i decided that the view will be bounded directly to the entities through the vm. (the vm will hold the entity reference, and binding will be o entity.propertyName...)
now i got a problem, when user start editing fields in one view, i wanna lock(make readonly) all other view that bound to the entity being under edit.
so my question is:
what changes do i need to do in my design for having the ability to know who(what view) started editing first, and when he finished.. and how to know about changed that came not from the ui(for not locking anything)
First you'll have to define exactly what it means for user to be "editing" an entity.
What action on the user's part signals they are beginning to edit an entity? Clearly when someone types something in a TextBox bound to a model field they are editing the entity. But what if someone clicks a button in the view that clears a property value in the model or sets it to a predefined value. Is that considered "editing" the entity? What if they change the settings of the view so that it shows fewer options and a ComboBox switches the value in the model to a new value because the old value is no longer listed?
What action on the user's part signals they are done editing an entity? Are they done when the focus leaves the control they are on? When the focus leaves the view? When they click "Ok" or "Save"?
Depending on the answers to these questions, several simple solutions present themselves. I'll explain one simple answer. If it doesn't apply please clarify the answers to the above questions.
Supposing:
Any change made to a model object except a data refresh from the database is considered editing, whether it be done with a button, checkbox, etc
The view that contains the focus is considered to be the one who is making the change
"Editing" ends when the view loses focus or the user saves the data.
Then the following will work:
Add a "Reloading" property either as a static property or somewhere within your model
In your data reloading code, set this property "true" and in a finally block set it "false" again
In your model object (or in a data structure shared between your view models and mapped from the model using a weak dictionary), add a property that contains the view model of the view that is currently editing the entity
In your view, add a PropertyChanged handler to your model object when the view model is attached
In the handler, if: a. The Reloading flag is false, b. No view is currently editing the entity, and c. This view's IsKeyboardFocusWithin is true, then record the fact that this view is currently editing the entity
In every view model, attach a handler to the "CurrentlyEditorView" property mentioned in step 3 (either directly or through the separate data structure). Whenever this propety changed, if it is non-null and not the current view model, set an inherited "Locked" property causing the view to lock.
In the view, add a LostFocus event handler that checks if the model's current view is this one, and if so clears it.
Also add a handler for the Save command that does the same thing.
It would really depend on your program structure. I have some similar requirements and I did this in my primaryshell view...
<Grid wpfi:VisualStateAssistant.CurrentVisualState="{Binding Path=CurrentVisualState}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="640" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="480" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ActiveFormStateGroup">
<VisualStateGroup.Transitions>
</VisualStateGroup.Transitions>
<VisualState x:Name="Searching">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="SearchHeaderView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="SearchNavigationView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="SearchResultsView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="DoctorsModuleShell">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="DoctorsModuleNavigationView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="DoctorEdit">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="SearchHeaderView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="SearchNavigationView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="SearchResultsView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="DoctorsModuleShell">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="DoctorsModuleNavigationView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="VisualAlertsStateGroup">
<VisualStateGroup.Transitions>
</VisualStateGroup.Transitions>
<VisualState x:Name="DialogShowing">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="DialogNotShowing">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="IsWaiting">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="WaitControl">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="IsNotWaiting">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="WaitControl">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DialogFormsStateGroup">
<VisualStateGroup.Transitions>
</VisualStateGroup.Transitions>
<VisualState x:Name="ShowContactInfoEdit">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="ContactInfoDatagridView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="HideContactInfoEdit">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="ContactInfoDatagridView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ShowDoctorTaxonomyEdit">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="DoctorsTaxonomyEditView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="HideDoctorTaxonomyEdit">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="DoctorsTaxonomyEditView">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<DockPanel Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="3"
Grid.RowSpan="3">
<!--TOP-->
<Grid ShowGridLines="False"
DockPanel.Dock="Top">
<views:SearchHeaderView x:Name="SearchHeaderView" />
</Grid>
<!--BOTTOM-->
<Grid ShowGridLines="false"
DockPanel.Dock="Bottom">
<views:SearchNavigationView x:Name="SearchNavigationView" />
<views:DoctorsModuleNavigationView x:Name="DoctorsModuleNavigationView"
Visibility="Collapsed" />
</Grid>
<!--FILL-->
<Grid ShowGridLines="False">
<views:SearchResultsView x:Name="SearchResultsView" />
<views:DoctorsModuleShell x:Name="DoctorsModuleShell"
Visibility="Collapsed" />
</Grid>
</DockPanel>
<Rectangle x:Name="rectangle"
RadiusX="2"
RadiusY="2"
Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="3"
Grid.RowSpan="3"
Fill="{StaticResource modalFormHitTestRectangleBrush}"
IsHitTestVisible="True"
Visibility="Collapsed" />
<controls:WaitingControl x:Name="WaitControl"
Width="100"
Height="100"
Visibility="Collapsed"
Grid.Column="1"
Grid.Row="1" />
<views:ContactInfoDatagridView x:Name="ContactInfoDatagridView"
Grid.Column="1"
Grid.Row="1"
Visibility="Collapsed" />
<views:DoctorsTaxonomyEditView x:Name="DoctorsTaxonomyEditView"
Grid.Column="1"
Grid.Row="1"
Visibility="Collapsed" />
</Grid>
Basically I databound my visualstatemanager to a property on my primary viewmodel that would trigger various visual states depending on an enum I created. I got the best help for doing that from Karl Shifflets Stuff Application.
An option would be to use an EventAggegator or use the Mediator pattern to alert other view models that a particular entity instance is under edit. Those viewmodels can set a property IsReadonly = true which can be bound in xaml to make the controls readonly.
Just rasie an out of edit event to tell those viewmodels that it is no longer in reaonly mode.
If you are binding directly to the entity it should be implementing INotifyPropertyChanged which your view model can listen to in order to detect the first edit taking place.
HTH