master/detail보기가있는 wpv/mvvm-light/vb.net 응용 프로그램이 있습니다. 이보기에는 클라이언트의 목록 상자와 고객이 클라이언트를보고 편집 할 수있는 클라이언트 세부 정보의 상세보기가 있습니다.Mvvm - Wpf Listbox, vb.net의 변경 사항 취소
새 클라이언트를 목록 상자에서 선택하면 사용자가 변경 사항을 저장하라는 메시지를 표시하는 기능을 추가하려고합니다. 사용자가 메시지 상자에서 예를 선택한 다음 변경 사항을 저장하고 없으면 변경 사항을 무시하고 이전 선택한 항목을 원래 값으로 되 돌립니다. 이 모든 것이 잘 작동합니다.
내 문제는 사용자가 새 클라이언트를 선택하고 메시지 상자에 변경 사항을 저장하라는 메시지가 표시되면 목록 상자가 동기화되지 않는다는 것입니다. 목록 상자에 선택된 새 클라이언트가 표시되지만 상세보기에는 여전히 이전 클라이언트가 표시된다는 의미입니다. 이상한 점은 드물게 제대로 작동한다는 것입니다.
<UserControl x:Class="FTC.View.ClientListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FTC_Application"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="900">
<ListBox
Grid.Column="1"
Width="350"
Style="{DynamicResource FTC_ListBox}"
ItemTemplate="{DynamicResource FTC_ClientListTemplate}"
ItemContainerStyle="{DynamicResource FTC_ListItem}"
ItemsSource="{Binding ClientViewSource.View}"
SelectedItem="{Binding Path=Selection, Mode=TwoWay}"
/>
<ContentControl DataContext="{Binding Path=Selection, Mode=TwoWay}" >
<!--all the display stuff goes here for the detail view-->
</ContentControl>
</UserControl>
다음은 목록 상자의 selectedItem가이 바인딩되는 뷰 모델의 속성입니다 :
다음
내이다. 세부 정보를 표시하는 내용 컨트롤의 바인딩이기도합니다.Public Property Selection As client
Get
Return Me._Selection
End Get
Set(ByVal value As client)
''capture current value of selection
_PreviousClient = _Selection
''If they are the same,
If value Is _PreviousClient Then
Return
End If
' Note that we actually change the value for now.This is necessary because WPF seems to query the
' value after the change. The list box likes to know that the value did change.
If Me._Selection.HasChanges = True And _Selection.HasErrors = False Then
'If HasChangesPrompt(value) = True Then
' ''user rejects saving changes, exit property
' Return
'End If
If FTCMessageBox.Show("Do you want to save your changes", "Unsaved Changes", MessageBoxButton.YesNo, MessageBoxImage.Warning) = MessageBoxResult.No Then
''SELECTION IS CANCELLED
' change the value back, but do so after the UI has finished it's current context operation.
Application.Current.Dispatcher.BeginInvoke(New Action(Sub()
'' revert the current selected item to its original values and reset its HasCHanges tracking
objHelper.CopyProperties(_OriginalClient, _Selection)
_Selection.HasChanges = False
RaisePropertyChanged(ClientSelectedPropertyName)
''continue with listbox selection changing to the new value for selection
_ClientCollectionViewSource.View.MoveCurrentTo(value)
End Sub), DispatcherPriority.Normal, Nothing)
Return
Else
''save changes to database
SaveExecute()
End If
End If
_Selection = value
_Selection.HasChanges = False
RaisePropertyChanged(ClientSelectedPropertyName)
''clone the unchanged version of the current selected client on na original variable
objHelper.CopyProperties(_Selection, _OriginalClient)
End Set
End Property
SO 아이디어는 사용자가 변경 사항을 저장하지 않을 경우, 클라이언트의 원래 값은 다음 UI가 업데이트되어, 현재 값보다 (반사를 사용하여) 복사되어 있고 선택에에 계속 사용자가 선택한 새 값 제가 위에서 말한 것처럼하지만, 목록 상자 내가 다음 줄에 하드 코드를 피곤하더라도이 변경 내용을 반영하지 않습니다
''continue with listbox selection changing to the new value for selection
_ClientCollectionViewSource.View.MoveCurrentTo(value)
내가 솔루션을 사용자 정의하는 작업으로이 솔루션을 가지고 게시 HERE
수 누구든지 내 목록 상자가 동기화되지 않는 이유를 알아내는 데 도움이됩니다. 사전
먼저
답장을 보내 주셔서 감사합니다. 나는 세터의 코드 양에 대해서도 불편하다. 그러나 MVVM 패턴을 따르려고하므로 UI보기를 ViewModel에서 분리해야합니다. 그래서 view.xaml 객체의 이벤트 뒤에 간단한 코드를 사용할 수 없습니다. 따라서 뷰 모델 코드에서이를 관리해야하는 방법과 선택 항목이 변경 될 때 실행되는 유일한 코드는 선택 개체에 대한 설정자입니다. 그래서 나는 그 변화를 취소하기위한 논리를 그 안에 넣었습니다. 내가 할 수있는 또 다른 방법을 안다. –