我正在尝试计划基于mvvm的基础架构,我决定通过vm将视图直接绑定到实体。 (vm将保存实体引用,绑定将为entity.propertyName ...)
现在我遇到了一个问题,当用户开始在一个视图中编辑字段时,我想锁定(make readonly)绑定到正在编辑的实体的所有其他视图。
所以我的问题是: 在我的设计中我需要做些什么改变才能知道谁(什么视图)首先开始编辑,何时完成...以及如何知道改变不是来自ui(因为没有锁定任何东西)< / p>
答案 0 :(得分:1)
首先,您必须准确定义用户“编辑”实体的含义。
用户的哪些操作表明他们开始编辑实体?很明显,当有人在绑定到模型字段的TextBox中键入内容时,他们正在编辑实体。但是,如果有人单击视图中的按钮来清除模型中的属性值或将其设置为预定义值,该怎么办?那被认为是“编辑”实体吗?如果他们更改视图的设置以便显示更少的选项,并且ComboBox将模型中的值切换为新值,因为旧的值不再列出会怎样?
用户的哪些操作表明他们编辑了一个实体?当焦点离开他们所控制的控件时,它们是否完成?当焦点离开视图时?当他们点击“确定”或“保存”?
根据这些问题的答案,可以使用几种简单的解决方案。我将解释一个简单的答案。如果不适用,请澄清上述问题的答案。
假设:
然后以下内容将起作用:
答案 1 :(得分:0)
这实际上取决于你的程序结构。我有一些类似的要求,我在我的原始视图中做到了这一点......
<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>
基本上我将visualstatemanager数据绑定到我的主视图模型上的属性,该属性将根据我创建的枚举触发各种视觉状态。我从Karl Shifflets Stuff Application那里得到了最好的帮助。
答案 2 :(得分:0)
一个选项是使用EventAggegator
或使用Mediator模式来警告其他视图模型正在编辑特定实体实例。那些视图模型可以设置一个属性IsReadonly = true
,它可以绑定在xaml中以使控件只读。
刚刚编辑一个编辑事件,告诉那些视图模型它不再处于reaonly模式。
如果您直接绑定到实体,它应该实现您的视图模型可以监听的INotifyPropertyChanged
,以便检测第一次编辑。
HTH