我这里有一个场景…(很抱歉写了这么长一篇文章)
我有TreeView(绑定到手机(不同类型)的可观察集合),我有一个contentCOntrol,其内容绑定设置为TreeView的selectedItem
代码…
<Border Grid.Column="2">
<ContentControl Name="userControlContentControl"
Content="{Binding ElementName=PhoneTreeViewUserControl,
Path=SelectedItem,
Converter={StaticResource ResourceKey=rightDisplayConverter}}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type EntityLayer:Settings}">
<ViewLayer:SettingsView />
</DataTemplate>
<DataTemplate DataType="{x:Type EntityLayer:CandyBarPhones}">
<ViewLayer:CandyBarPhonesListView />
</DataTemplate>
<DataTemplate DataType="{x:Type EntityLayer:CandyBarPhone}">
<ViewLayer:CandyBarPhoneView />
</DataTemplate>
<DataTemplate DataType="{x:Type EntityLayer:QwertyPhones}">
<ViewLayer:QwertyPhonesListView />
</DataTemplate>
<DataTemplate DataType="{x:Type EntityLayer:QuertyPhone}">
<ViewLayer:QuertyPhoneView />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Border>
问题是,当我选择一个电话从TreeView(一个特定的视图是由contentcontrol填充)我希望传递UniqueId(PhoneBase有那个属性)到我的视图的ViewModel,也在ViewModel中触发一个函数,这样它就可以从BusinessLayer获得数据…并初始化ViewModel和它的所有属性。
CodeBehind for UserControl
区域类- QuertyPhoneView
/// <summary>
/// Interaction logic for ProductIdEditorView.xaml
/// </summary>
public partial class QuertyPhoneView : BaseUserControl
{
QertyPhoneViewModel quertyPhoneViewModel;
#region Constructor
/// <summary>
/// </summary>
public ProductIdEditorView()
{
InitializeComponent();
quertyPhoneViewModel =
new quertyPhoneViewModel ();
this.DataContext = quertyPhoneViewModel;
}
# endregion
}
#endregion
也在ViewModel我有信使注册....但是每次我选择另一种电话类型,然后选择前一种类型,信使就会再次注册,而不会取消之前的注册…(我在Messenger中没有任何注销方法,使用Marlon的Mediator V2),如果使用15-20分钟左右,它会使应用程序非常慢
ViewModel for a Typical View.
区域类- QuertyPhoneViewModel
/// <summary>
/// QuertyPhoneViewModel
/// </summary>
public class QuertyPhoneViewModel : BaseViewModel
{
# region Member Variables
/// <summary>
/// quertyPhoneDetails
/// </summary>
private QuertyPhone quertyPhoneDetails;
/// <summary>
/// oldQuertyPhoneDetails
/// </summary>
private ProductId oldQuertyPhoneDetails;
/// <summary>
/// productIds
/// </summary>
private QuertyPhones quertyPhones;
/// <summary>
/// productIdModel
/// </summary>
private readonly QuertyPhoneModal quertyPhoneModal;
/// <summary>
/// log
/// </summary>
private static readonly ILog log =
LogManager.GetLogger(typeof (QuertyPhoneViewModel));
/// <summary>
/// selectedCalTblName
/// </summary>
private CalibrationTable selectedCalTblName;
# endregion
# region Constructor
/// <summary>
/// QuertyPhoneViewModel
/// </summary>
public QuertyPhoneViewModel()
{
RegisterForMessage();
quertyPhoneModal= new QuertyPhoneModal();
if (QuertyPhoneDetails == null)
{
//Requesting TreeViewUsersontrol To send Details
// I wish to remove these registrations
Messenger.NotifyColleagues<ProductId>(
MessengerMessages.SEND_SELECTED_PHONE, QuertyPhoneDetails);
}
CancelPhoneDetailsChangeCommand = new RelayCommand(CancelQuertyPhoneDetailsChanges,
obj => this.IsDirty);
SavePhoneDetailsChangeCommand = new RelayCommand(SaveQuertyPhoneDetailsToTree,
CanSaveQuertyPhoneDetailsToTree);
}
# endregion
# region Properties
/// <summary>
/// CalibrationTblNameList
/// </summary>
public ObservableCollection<CalibrationTable> CalibrationTblNameList { get; set; }
/// <summary>
/// CancelPhoneDetailsChangeCommand
/// </summary>
public ICommand CancelPhoneDetailsChangeCommand { get; set; }
/// <summary>
/// SavePhoneDetailsChangeCommand
/// </summary>
public ICommand SavePhoneDetailsChangeCommand { get; set; }
/// <summary>
/// QuertyPhoneDetails
/// </summary>
public ProductId QuertyPhoneDetails
{
get { return quertyPhoneDetails; }
set
{
quertyPhoneDetails = value;
OnPropertyChanged("QuertyPhoneDetails");
}
}
/// <summary>
/// SelectedCalTblName
/// </summary>
public CalibrationTable SelectedCalTblName
{
get { return selectedCalTblName; }
set
{
selectedCalTblName = value;
OnPropertyChanged("SelectedCalTblName");
if (selectedCalTblName != null)
{
QuertyPhoneDetails.CalibrationTableId =
selectedCalTblName.UniqueId;
}
}
}
/// <summary>
/// QuertyPhones
/// </summary>
public QuertyPhones QuertyPhones
{
get { return productIds; }
set
{
productIds = value;
OnPropertyChanged("QuertyPhones");
}
}
# endregion
# region Public Methods
# endregion
# region Private Methods
/// <summary>
/// RegisterForMessage
/// I wish to remove these registrations too
/// </summary>
private void RegisterForMessage()
{
log.Debug("RegisterForMessage" + BaseModel.FUNCTION_ENTERED_LOG);
Messenger.Register(MessengerMessages.RECIEVE_SELECTED_PHONE,
(Action<ProductId>) (o =>
{
if (o != null)
{
QuertyPhoneDetails
=
o.Clone() as
ProductId;
AttachChangeEvents
();
oldQuertyPhoneDetails
= o;
SetCalibrationTables
();
}
}));
Messenger.Register(MessengerMessages.REFRESH_PHONEDETILAS,
(Action<string>)
(o =>
{
GetOldQuertyPhoneDetails(o);
this.IsDirty = false;
}));
log.Debug("RegisterForMessage" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// CanSaveQuertyPhoneDetailsToTree
/// </summary>
/// <param name = "obj"></param>
/// <returns></returns>
private bool CanSaveQuertyPhoneDetailsToTree(object obj)
{
return this.IsDirty && ValidateQuertyPhoneDetails();
}
/// <summary>
/// SaveQuertyPhoneDetailsToTree
/// </summary>
/// <param name = "obj"></param>
private void SaveQuertyPhoneDetailsToTree(object obj)
{
log.Debug("SaveQuertyPhoneDetails" + BaseModel.FUNCTION_ENTERED_LOG);
if (Utility.IsStringNullOrEmpty(QuertyPhoneDetails.CalibrationTableId))
{
MessageBoxResult result =
ShowMessageDialog(
"Calibration Table name is not set.Do you wish to proceed?",
"Save ProductId",
MessageBoxButton.YesNo,
MessageBoxImage.Exclamation);
if (result == MessageBoxResult.Yes)
{
SaveDetails();
}
}
else
{
SaveDetails();
}
log.Debug("SaveQuertyPhoneDetails" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// SaveDetails
/// </summary>
private void SaveDetails()
{
log.Debug("SaveDetails" + BaseModel.FUNCTION_ENTERED_LOG);
if (productIdModel.SaveQuertyPhoneDetails(QuertyPhoneDetails))
{
UpdateProgressbarStatus(
"ProductId " + QuertyPhoneDetails.Specs
+ " saved successfully.",
false);
this.IsDirty = false;
}
else
{
ShowMessageDialog(
"ProductId " + QuertyPhoneDetails.Specs +
" not saved successfully.",
"Save ProductId",
MessageBoxButton.OK,
MessageBoxImage.Error);
UpdateProgressbarStatus(
"ProductId " + QuertyPhoneDetails.Specs
+ " not saved successfully.",
false);
}
log.Debug("SaveDetails" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// SetCalibrationTables
/// </summary>
private void SetCalibrationTables()
{
log.Debug("SetCalibrationTables" + BaseModel.FUNCTION_ENTERED_LOG);
CalibrationTblNameList =
productIdModel.FileData.CalibrationTables.CalibrationTableList;
SelectedCalTblName = (CalibrationTblNameList.Where(
calibrationTable =>
calibrationTable.UniqueId.Equals(
QuertyPhoneDetails.CalibrationTableId))).FirstOrDefault();
log.Debug("SetCalibrationTables" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// CancelQuertyPhoneDetailsChanges
/// </summary>
/// <param name = "obj"></param>
private void CancelQuertyPhoneDetailsChanges(object obj)
{
log.Debug("CancelQuertyPhoneDetailsChanges" + BaseModel.FUNCTION_ENTERED_LOG);
GetOldQuertyPhoneDetails(QuertyPhoneDetails.Specs);
this.IsDirty = false;
productIdModel.SelectMainProductList();
Messenger.NotifyColleagues<bool>(
MessengerMessages.POP_UP_CLOSE_REQUEST, true);
log.Debug("CancelQuertyPhoneDetailsChanges" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// GetOldQuertyPhoneDetails
/// </summary>
/// <param name = "idNumber"></param>
private void GetOldQuertyPhoneDetails(string idNumber)
{
log.Debug("GetOldQuertyPhoneDetails" + BaseModel.FUNCTION_ENTERED_LOG);
if (!string.IsNullOrEmpty(idNumber))
{
ProductId tempQuertyPhoneDetails =
productIdModel.GetProduct(idNumber).Clone() as ProductId;
if (tempQuertyPhoneDetails != null)
{
QuertyPhoneDetails = tempQuertyPhoneDetails;
QuertyPhoneDetails.Reset();
}
AttachChangeEvents();
}
log.Debug("GetOldQuertyPhoneDetails" + BaseModel.FUNCTION_EXIT_LOG);
}
/// <summary>
/// AttachChangeEvents
/// </summary>
private void AttachChangeEvents()
{
log.Debug("AttachChangeEvents" + BaseModel.FUNCTION_ENTERED_LOG);
QuertyPhoneDetails.Reset();
QuertyPhoneDetails.PropertyChanged -= OnQuertyPhoneDetailsChanged;
QuertyPhoneDetails.PropertyChanged += OnQuertyPhoneDetailsChanged;
log.Debug("AttachChangeEvents" + BaseModel.FUNCTION_EXIT_LOG);
}
private void OnQuertyPhoneDetailsChanged(object sender,
PropertyChangedEventArgs e)
{
if (QuertyPhoneDetails.Changes.Count > 0)
{
OnItemDataChanged(sender, e, QuertyPhoneDetails.Changes.Count);
}
}
/// <summary>
/// ValidateQuertyPhoneDetails
/// </summary>
/// <returns></returns>
private bool ValidateQuertyPhoneDetails()
{
log.Debug("ValidateQuertyPhoneDetails" + BaseModel.FUNCTION_ENTERED_LOG);
if (
!Utility.IsValidAlphanumeric(
QuertyPhoneDetails.ControllerInformation)
||
(!Utility.IsValidAlphanumeric(QuertyPhoneDetails.PhoneId))
|| (!Utility.IsValidAlphanumeric(QuertyPhoneDetails.Specs)))
{
QuertyPhoneDetails.ErrorMsg =
AddTreeNodeViewModel.ERROR_NO_ALPHANUMERIC;
return false;
}
QuertyPhoneDetails.ErrorMsg = string.Empty;
log.Debug("ValidateQuertyPhoneDetails" + BaseModel.FUNCTION_EXIT_LOG);
return true;
}
# endregion
}
#endregion
我完全不知道该怎么办…在这方面的任何帮助都是GR8!!由于
为什么不让你的ParentViewModel跟踪SelectedItem而不是让你的视图做它?我个人讨厌在我的View中做任何类型的业务逻辑。它应该只是一个漂亮的图层,位于我的ViewModels之上,使用户更容易与它们交互。
例如,你的PhonesViewModel可能有:
// Leaving out get/set method details for simplicity
Observable<QuertyPhone> Phones { get; set; }
QuertyPhone SelectedPhone { get; set; }
ICommand SaveSelectedPhoneCommand { get; }
ICommand CancelSelectedPhoneCommand { get; }
你的视图看起来就像这样:
<DockPanel>
<TreeView DockPanel.Dock="Left"
ItemsSource="{Binding Phones}"
SelectedItem="{Binding SelectedPhone}" />
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<Button Content="{Binding SaveCommand}" />
<Button Content="{Binding CancelCommand}" />
</StackPanel>
<ContentControl Content="{Binding SelectedPhone} />
</DockPanel>
我将在您的QuertyPhone
模型中保留验证,但将数据访问移动到ViewModel。在我看来,你的模型应该只是愚蠢的数据对象。您也只需要在一个地方(您的ViewModel)注册消息传递,如果您需要在SelectedPhone更改时执行任何操作,只需在PropertyChanged事件中执行即可。
作为旁注,我忘了如果你可以绑定一个TreeView的SelectedItem或不,但如果不是你可以使用一个ListBox样式看起来像一个TreeView,或者在过去我已经添加了IsSelected
属性到我的TreeView数据对象,并绑定TreeViewItem.IsSelected
属性。