将值从视图发送到视图模型



我这里有一个场景…(很抱歉写了这么长一篇文章)

我有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属性。

相关内容

  • 没有找到相关文章

最新更新