Múltiples instancias de ViewModel -- # campo con wpf campo con xaml camp Relacionados El problema

Multiple Instances of ViewModel


0
vote

problema

Español

Tengo una sola vista que realiza tareas a través de ICOMMAND. La vista realiza una tarea en una lista de elementos seleccionados de un ListView. Recibo la lista de elementos seleccionados a través del evento Selection_Changed en el código detrás. La acción en esos artículos se realiza a través de un comando. La lista de elementos seleccionados en el modelo de vista no coincide entre las dos llamadas. La lista de elementos seleccionados Después de los elementos seleccionados es correcta, la lista de elementos seleccionados al que hace referencia el comando está vacía. Determiné que la lista no se reinicializa ni se borra revisando las direcciones de memoria de las listas. Las direcciones de memoria son diferentes.

¿Por qué tengo dos instancias de los programas seleccionados?

Ver xaml

  ... <Window.Resources>     <viewModels:AdminViewModel x:Key="ViewModel" /> </Window.Resources> <Window.DataContext>     <viewModels:AdminViewModel/> </Window.DataContext> <ListView x:Name="lvCustomerPrices"      HorizontalAlignment="Left"      Margin="14,82,0,32"      Width="1362"      ItemsSource="{Binding Prices}"      Grid.ColumnSpan="3"      SelectionChanged="lvCustomerPrices_SelectionChanged"> ...   

Ver código detrás

  public partial class ExportAdminView : Window {     protected AdminViewModel ViewModel     {         get { return (AdminViewModel)Resources["ViewModel"]; }     }      public ExportAdminView()     {         InitializeComponent();     }      private void lvCustomerPrices_SelectionChanged(object sender, SelectionChangedEventArgs e)     {         ViewModel.SetSelectedPrices(lvCustomerPrices.SelectedItems.Cast<DailyCustomerPrice>());     } }   

Ver modelo

  public class AdminViewModel : INotifyPropertyChanged {     public List<DailyCustomerPrice> SelectedPrices { get; set; } = new List<DailyCustomerPrice>();      public bool CanExportToEmail => (SelectedPrices.Count > 0 && !string.IsNullOrEmpty(ExportEmailAddress));      public ICommand ExportPricesToEmailCommand { get; set; }      public AdminViewModel()     {         ExportPricesToEmailCommand = new RelayCommand(ExportPrices, () => CanExportToEmail);         PriceEffectiveDate = DateTime.Now.Date.AddDays(1);     }      public void SetSelectedPrices(IEnumerable<DailyCustomerPrice> selectedItems)     {         SelectedPrices.Clear();         SelectedPrices.AddRange(selectedItems);     } }   

Relaycommand (necesito limpiar esto y hacer una clase separada para los parámetros)

  public class RelayCommand : ICommand {     private Action<object> _executeWithParameter;     private Action _execute;     private Func<bool> _canExecute;     private event EventHandler CanExecuteChangedInternal;      public RelayCommand(Action<object> execute)         : this(execute, DefaultCanExecute)     {}      public RelayCommand(Action execute) : this(execute, DefaultCanExecute)     {}      public RelayCommand(Action execute, Func<bool> canExecute)     {         if (execute == null)             throw new ArgumentNullException(nameof(execute));          if (canExecute == null)             throw new ArgumentNullException(nameof(canExecute));          this._execute = execute;         this._canExecute = canExecute;     }       public RelayCommand(Action<object> execute, Func<bool> canExecute)     {         if (execute == null)         {             throw new ArgumentNullException(nameof(execute));         }          if (canExecute == null)         {             throw new ArgumentNullException(nameof(canExecute));         }          this._executeWithParameter = execute;         this._canExecute = canExecute;     }      public event EventHandler CanExecuteChanged     {         add         {             CommandManager.RequerySuggested += value;             this.CanExecuteChangedInternal += value;         }          remove         {             CommandManager.RequerySuggested -= value;             this.CanExecuteChangedInternal -= value;         }     }      public bool CanExecute()     {         return _canExecute();     }      public bool CanExecute(object parameter)     {         return CanExecute();     }      public void Execute(object parameter)     {         Execute();     }      bool ICommand.CanExecute(object parameter)     {         return CanExecute();     }      void ICommand.Execute(object parameter)     {         Execute();     }      public void Execute()     {         _execute();     }      public void OnCanExecuteChanged()     {         EventHandler handler = this.CanExecuteChangedInternal;         //DispatcherHelper.BeginInvokeOnUIThread(() => handler.Invoke(this, EventArgs.Empty));         handler?.Invoke(this, EventArgs.Empty);     }      public void Destroy()     {         _canExecute = () => false;         _executeWithParameter = _ => { return; };         _execute = null;     }      private static bool DefaultCanExecute()     {         return true;     } }   

Los programas seleccionados en la propiedad AdminViewModel.canexPorTtoEmail tiene una dirección de memoria diferente a las programas seleccionadas en el método SetSelectEPRICES.

Necesito que estos estén sincronizados.

Original en ingles

I have a single view that performs tasks via ICommand. The view performs a task on a list of selected items from a listview. I get the list of selected item's via the selection_changed event in the code behind. The action on those items is performed via a command. The list of selected items in the view model doesn't match between the two calls. The list of selected items after items are selected is correct, the list of selected items referenced by the command is empty. I determined the list isn't being reinstantiated or cleared by checking the memory addresses of the lists. The memory addresses are different.

Why do I have two instances of SelectedPrices?

View XAML

... <Window.Resources>     <viewModels:AdminViewModel x:Key="ViewModel" /> </Window.Resources> <Window.DataContext>     <viewModels:AdminViewModel/> </Window.DataContext> <ListView x:Name="lvCustomerPrices"      HorizontalAlignment="Left"      Margin="14,82,0,32"      Width="1362"      ItemsSource="{Binding Prices}"      Grid.ColumnSpan="3"      SelectionChanged="lvCustomerPrices_SelectionChanged"> ... 

View Code Behind

public partial class ExportAdminView : Window {     protected AdminViewModel ViewModel     {         get { return (AdminViewModel)Resources["ViewModel"]; }     }      public ExportAdminView()     {         InitializeComponent();     }      private void lvCustomerPrices_SelectionChanged(object sender, SelectionChangedEventArgs e)     {         ViewModel.SetSelectedPrices(lvCustomerPrices.SelectedItems.Cast<DailyCustomerPrice>());     } } 

View Model

public class AdminViewModel : INotifyPropertyChanged {     public List<DailyCustomerPrice> SelectedPrices { get; set; } = new List<DailyCustomerPrice>();      public bool CanExportToEmail => (SelectedPrices.Count > 0 && !string.IsNullOrEmpty(ExportEmailAddress));      public ICommand ExportPricesToEmailCommand { get; set; }      public AdminViewModel()     {         ExportPricesToEmailCommand = new RelayCommand(ExportPrices, () => CanExportToEmail);         PriceEffectiveDate = DateTime.Now.Date.AddDays(1);     }      public void SetSelectedPrices(IEnumerable<DailyCustomerPrice> selectedItems)     {         SelectedPrices.Clear();         SelectedPrices.AddRange(selectedItems);     } } 

RelayCommand (I need to clean this up and make a separate class for parameters)

public class RelayCommand : ICommand {     private Action<object> _executeWithParameter;     private Action _execute;     private Func<bool> _canExecute;     private event EventHandler CanExecuteChangedInternal;      public RelayCommand(Action<object> execute)         : this(execute, DefaultCanExecute)     {}      public RelayCommand(Action execute) : this(execute, DefaultCanExecute)     {}      public RelayCommand(Action execute, Func<bool> canExecute)     {         if (execute == null)             throw new ArgumentNullException(nameof(execute));          if (canExecute == null)             throw new ArgumentNullException(nameof(canExecute));          this._execute = execute;         this._canExecute = canExecute;     }       public RelayCommand(Action<object> execute, Func<bool> canExecute)     {         if (execute == null)         {             throw new ArgumentNullException(nameof(execute));         }          if (canExecute == null)         {             throw new ArgumentNullException(nameof(canExecute));         }          this._executeWithParameter = execute;         this._canExecute = canExecute;     }      public event EventHandler CanExecuteChanged     {         add         {             CommandManager.RequerySuggested += value;             this.CanExecuteChangedInternal += value;         }          remove         {             CommandManager.RequerySuggested -= value;             this.CanExecuteChangedInternal -= value;         }     }      public bool CanExecute()     {         return _canExecute();     }      public bool CanExecute(object parameter)     {         return CanExecute();     }      public void Execute(object parameter)     {         Execute();     }      bool ICommand.CanExecute(object parameter)     {         return CanExecute();     }      void ICommand.Execute(object parameter)     {         Execute();     }      public void Execute()     {         _execute();     }      public void OnCanExecuteChanged()     {         EventHandler handler = this.CanExecuteChangedInternal;         //DispatcherHelper.BeginInvokeOnUIThread(() => handler.Invoke(this, EventArgs.Empty));         handler?.Invoke(this, EventArgs.Empty);     }      public void Destroy()     {         _canExecute = () => false;         _executeWithParameter = _ => { return; };         _execute = null;     }      private static bool DefaultCanExecute()     {         return true;     } } 

The SelectedPrices in the AdminViewModel.CanExportToEmail property has a different memory address than the SelectedPrices in the SetSelectedPrices method.

I need these to be in sync.

        
         
         

Lista de respuestas

4
 
vote
vote
La mejor respuesta
 

Para solucionar su problema, elimine su LiveData4 de xaml o de código-detrás.

Para acceder a él en el código detrás, agarrar su LiveData5 con LiveData6 .

vítores

 

To fix your issue, either remove your AdminViewModel from XAML or from Code-Behind.

To get access to it in Code-Behind, grab your AdminViewModel with (AdminViewModel)this.DataContext.

Cheers

 
 
1
 
vote

Eliminar

  LiveData7  

y prueba esto;

  LiveData8  
 

Remove

<Window.Resources>     <viewModels:AdminViewModel x:Key="ViewModel" /> </Window.Resources> <Window.DataContext>     <viewModels:AdminViewModel/> </Window.DataContext> 

And try this;

public ExportAdminView() {    this.DataContext = new AdminViewModel();    InitializeComponent();   } 
 
 

Relacionados problema

0  Borde de validación del cuadro de texto  ( Textbox validation border ) 
Actualmente tengo el siguiente table-layout:fixed1 , lo que significa una entrada no válida, alrededor de TextBox es en una aplicación. Simplemente no me...

5  Controlando el guión gráfico de USERCONTROL desde la ventana principal en WPF usando solo XAML  ( Controlling a usercontrols storyboard from the parent window in wpf using only ) 
He creado una aplicación de prueba muy simple para tratar de resolver este problema que me describe un compañero de trabajo. Pudo desencadenarlo en C #, pero ...

0  HierarchicalDataTemplate y TreeView error de compilación vinculante  ( Hierarchicaldatatemplate and treeview binding compilation error ) 
Me han puesto en marcha un control de usuario y poner un control TreeView en eso. El archivo XAML se ve como sigue. Estoy utilizando un HierarchicalDataTempla...

18  WPF Designer "No se pudo crear una instancia de tipo"  ( Wpf designer could not create an instance of type ) 
En mi UI XAML, estoy heriendo esencialmente de una clase "Baseview" que contiene funcionalidad común a varias formas, sin embargo, esto está impidiendo que el...

0  ListView ScrollBar desordena mi diseño  ( Listview scrollbar messes up my layout ) 
Tengo un cuadro de lista de WPF que normalmente muestra 4 o 5 artículos. Para mi solicitud, eso significa que casi nunca tengo que mostrar una barra de despla...

1  VS2008 XAML Designer Exception "Clave no puede ser nulo" cuando se usa los estilos predeterminados de un Resourcestionary  ( Vs2008 xaml designer exception key cannot be null when using default styles fr ) 
Estoy usando un elemento compartido para definir los estilos predeterminados y tener conflictos importantes con el Diseñador XAML en Visual Studio 2008. La t...

0  DataGrid se comportan anormalmente cuando los artículos son muy grandes  ( Datagrid behaving abnormally when itemsource is very large ) 
Estoy viendo un comportamiento anormal en DataGrid cuando la fuente de elemento es una lista muy grande (& gt; 4000), como las columnas están desapareciendo m...

2  ¿Cómo puedo aplicar un GRADIENTBRUSH a múltiples objetos consecutivos en XAML?  ( How can i apply a gradientbrush to multiple consecutive objects in xaml ) 
Tengo un bloque de texto y una línea que se sienta uno junto al otro en su propio Packpanel exclusivo. Necesito difundir mi LineArgradientBrush a través de ...

2  VS2010 no puede encontrar Tipo ControlTemplate Aunque System.Windows se hace referencia  ( Vs2010 cannot find type controltemplate even though system windows is referenced ) 
Estoy tratando de aprender Silverlight aquí, creando una plantilla de control personalizada, sin embargo, VS2010 se niega a reconocer el ControlTemplate E...

3  Error de Grido de WPF SharedSize  ( Wpf grid sharedsizegroup error ) 
Si ejecuta este código y haga clic en la pestaña 2 y luego vuelva a encender la pestaña 1, la aplicación se vuelve loco y comienza a rebotar los anchos de la ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos