некоторая проблема с mvvm - знание того, какой вид в данный момент редактирует объект - PullRequest
1 голос
/ 30 июня 2010

Я пытаюсь спланировать инфраструктуру на основе mvvm, я решил, что представление будет привязано непосредственно к объектам через vm.(виртуальная машина будет содержать ссылку на сущность, а привязка будет o entity.propertyName ...)

Теперь у меня возникла проблема, когда пользователь начинает редактировать поля в одном представлении, я хочу заблокировать (сделать только для чтения) вседругой вид, который привязан к редактируемой сущности.

, поэтому мой вопрос: какие изменения мне нужно сделать в моем дизайне, чтобы иметь возможность узнать, кто (какой вид) начал редактировать первым, и когда онзакончил .. и как узнать об изменениях, которые пришли не из пользовательского интерфейса (для того, чтобы ничего не блокировать)

Ответы [ 3 ]

1 голос
/ 30 июня 2010

Сначала вам нужно точно определить, что значит для пользователя «редактировать» сущность.

  1. Какое действие со стороны пользователя сигнализирует о том, что он начинает редактировать сущность?Очевидно, что когда кто-то печатает что-то в TextBox, привязанном к полю модели, он редактирует сущность.Но что делать, если кто-то нажимает кнопку в представлении, которая очищает значение свойства в модели или устанавливает его в предварительно определенное значение.Это считается «редактированием» объекта?Что если они изменят настройки представления, чтобы оно показывало меньше параметров, и ComboBox переключил значение в модели на новое значение, поскольку старое значение больше не отображается в списке?

  2. Чтодействия со стороны пользователя сигнализируют, что они закончили редактирование объекта?Они сделаны, когда фокус покидает контроль, на котором они находятся?Когда фокус покидает вид?Когда они нажимают «ОК» или «Сохранить»?

В зависимости от ответов на эти вопросы, возникает несколько простых решений.Я объясню один простой ответ.Если это не применимо, уточните ответы на вышеуказанные вопросы.

Предположим:

  1. Любое изменение, внесенное в объект модели, за исключением обновления данных из базы данных, считается редактированием,будет ли это сделано с помощью кнопки, флажка и т. д.
  2. Вид, содержащий фокус, считается тем, кто вносит изменение
  3. «Редактирование» заканчивается, когда вид теряет фокус илипользователь сохраняет данные.

Тогда сработает следующее:

  1. Добавьте свойство «Перезагружать» либо как статическое свойство, либо где-то в вашей модели
  2. В своем коде повторной загрузки данных установите это свойство "true", а в блоке finally установите его снова "false"
  3. В вашем объекте модели (или в структуре данных, совместно используемой вашими моделями представления и отображенной из(используя слабый словарь), добавьте свойство, которое содержит модель представления для представления, которое в данный момент редактирует сущность
  4. В вашем представлении добавьте обработчик PropertyChanged к вашемуodel объект, когда модель вида прикреплена
  5. В обработчике, если: a.Флаг перезарядки ложный, б.Нет представления, в настоящее время редактирующего объект, и c.IsKeyboardFocusWithin этого представления имеет значение true, затем запишите тот факт, что это представление в настоящее время редактирует сущность
  6. В каждой модели представления присоедините обработчик к свойству «CurrentEditorView», указанному на шаге 3 (напрямую или через отдельные данныесостав).Всякий раз, когда это свойство изменялось, если оно ненулевое и не является текущей моделью представления, установите унаследованное свойство «Заблокировано», заставляющее представление блокироваться.
  7. В представлении добавьте обработчик события LostFocus, который проверяет, является лиЭто текущее представление модели, и, если это так, оно очищается.
  8. Также добавьте обработчик для команды Сохранить, который делает то же самое.
0 голосов
/ 30 июня 2010

Можно использовать EventAggegator или использовать шаблон Mediator для оповещения других моделей представления о том, что конкретный экземпляр сущности редактируется.Этим моделям представления можно задать свойство IsReadonly = true, которое можно связать в xaml, чтобы сделать элементы управления доступными только для чтения.

Просто отправьте событие вне редактирования, чтобы сообщить этим моделям просмотра, что оно больше не находится в режиме реального времени.

Если вы связываетесь непосредственно с сущностью, она должна реализовывать INotifyPropertyChanged, которую ваша модель представления может прослушивать, чтобы обнаружить, что происходит первое редактирование.

HTH

0 голосов
/ 30 июня 2010

Это действительно зависит от структуры вашей программы.У меня есть некоторые аналогичные требования, и я сделал это в своем первичном представлении оболочки ...

<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 к свойству в моей основной view-модели, которая будет запускать различные визуальные состояния в зависимости от созданного мной перечисления.Я получил лучшую помощь для этого из приложения Karl Shifflets Stuff Application.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...