Si encuentras algún fallo con tu código o trabajo, recuerda probar siempre en un ambiente de testing antes aplicar el código al proyecto final.
Solución:
En primer lugar. Establecer dependencias de proyectos. ViewModel debe tener acceso Model. (Los proyectos de vista y modelo no tienen que hacer referencia a otros proyectos). Si yo fuera usted, haría un proyecto de inicio para transferir el control a ViewModel. Este proyecto “StartUp” debe ser WPF, todos los demás deben ser “biblioteca de clases”, pero no olvide agregar las referencias requeridas a los proyectos (por ejemplo, system.xaml para que su proyecto de vista cree controles de usuario).
Dependencias de proyectos: – Inicio -> ViewModel; (- ViewModel -> Ver; o evite esto con DI) – ViewModel -> Modelo; (Debería hacer otro proyecto para interfaces solo que estas son solo mis perversiones).
Proyecto de inicio: Ahora, en su proyecto de inicio (WPF) debe contener en (app.xaml.cs):
protected override void OnStartup(StartupEventArgs e)
// delete the startupuri tag from your app.xaml
base.OnStartup(e);
//this MainViewModel from your ViewModel project
MainWindow = new MainWindow(new MainViewModel());
La única cosa (Ventana) en su proyecto de inicio de wpf (para mostrar sus UserControls).
Contenido de MainWindow.xaml:
(y xaml.cs)
public partial class MainWindow : Window
public MainWindow(INotifyPropertyChanged ViewModel)
InitializeComponent();
this.DataContext = ViewModel;
this.Show();
Y eso es todo su proyecto StartUp WPF. De esta forma le dimos el control a su proyecto ViewModel.
(Está bien, es solo un extra, pero debería hacer un “ViewService” para manejar mis UserControls)
Interfaz para encontrar todas las vistas y hacer coincidir la vista con ViewModel.
public interface IControlView
INotifyPropertyChanged ViewModel get; set;
Creé un singleton para almacenar y hacer coincidir mis vistas con mis modelos de vista. (Puede omitir esta parte). Definí esto en Modelo proyecto.
public class ViewService where T : IControlView
private readonly List cache;
public delegate void ShowDelegate(T ResultView);
public event ShowDelegate Show;
public void ShowControl(INotifyPropertyChanged ViewModel)
if (Show != null)
Show(GetView(ViewModel));
#region Singleton
private static ViewService instance;
public static ViewService GetContainer
get
if (instance == null)
instance = new ViewService();
return instance;
private ViewService()
cache = new List();
var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes()).Where(r => typeof(T).IsAssignableFrom(r) && !r.IsInterface && !r.IsAbstract && !r.IsEnum);
foreach (Type type in types)
cache.Add(new WeakReference((T)Activator.CreateInstance(type)));
#endregion
private T GetView(INotifyPropertyChanged ViewModel)
T target = default(T);
foreach (var wRef in cache)
if (wRef.IsAlive && wRef.Target.GetType().IsEquivalentTo(typeof(Z)))
target = (T)wRef.Target;
break;
if(target==null)
target = (T)Activator.CreateInstance(typeof(Z));
if(ViewModel != null)
target.ViewModel = ViewModel;
return target;
Y ahora tiene un “servicio” para mostrar sus UserControls en la ventana principal de su
ViewModel:
public class MainViewModel : INotifyPropertyChanged
private IControlView _control;
public IControlView Control
get
return _control;
set
_control = value;
OnPropertyChanged();
public MainViewModel()
//Subscribe for the ViewService event:
ViewService.GetContainer.Show += ShowControl;
// in this way, here is how to set a user control to the window.
ViewService.GetContainer.ShowControl(new TheViewModel(yourDependencyItems));
//you can call this anywhere in your viewmodel project. For example inside a command too.
public void ShowControl(IControlView ControlView)
Control = ControlView;
//implement INotifyPropertyChanged...
protected void OnPropertyChanged([CallerMemberName] string name = "propertyName")
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
public event PropertyChangedEventHandler PropertyChanged;
Si no desea utilizar este “ViewService”. Simplemente cree una instancia de UserControl, haga coincidir DataContext of View con su ViewModel y otorgue esta vista a la propiedad Control. Aquí está su ViewModel con lista (todavía en el proyecto ViewMoldel).
public class TheViewModel
private readonly ObservableCollection listOfItems;
public ObservableCollection ListOfItems
get return listOfItems;
public ICommand SaveCheckedItemsText
get return new RelayCommand(CollectNamesOfSelectedElements);
public IEnumerable GetSelectedElements
get return listOfItems.Where(item=>item.CheckStatus);
public TheViewModel(IList dependencyItems)
listOfItems= new ObservableCollection(dependencyItems);
//here is your list...
private List selectedNames
//use this...
private void CollectNamesOfSelectedElements()
selectedNames = new List();
foreach(ISelectable item in GetSelectedElements)
//you should override the ToString in your model if you want to do this...
selectedNames.Add(item.ToString());
Artículo de RelayCommand
Vista: (Guarde aquí todos sus controles de usuario).
En su UserControl (xaml):
Y con la interfaz aquí está el código xaml.cs (para UserControls):
public partial class ListViewDatabaseStyle : UserControl, IControlView
public ListViewDatabaseStyle ()
InitializeComponent();
public INotifyPropertyChanged ViewModel
get
return (INotifyPropertyChanged)DataContext;
set
DataContext = value;
Y el ultimo es el Modelo proyecto con sus modelos:
public interface ISelectable
bool CheckStatus get; set;
public class CheckBoxListModel : INotifyPropertyChanged, ISelectable
private string text;
public string Text
get return text;
set
text = value;
RaiseChanged("Text");
private bool checkStatus;
public bool CheckStatus
get return checkStatus;
set
checkStatus = value;
RaiseChanged("CheckStatus");
private void RaiseChanged(string propName)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
public event PropertyChangedEventHandler PropertyChanged;
}
Disculpe los errores gramaticales en inglés, espero que haya entendido mi publicación.
Actualizar:
Utilice la técnica DI. para evitar la referencia a ver desde viewmodel. El servicio DI inyectará el objeto correcto con la inyección del constructor.
Nos puedes confirmar nuestra ocupación escribiendo un comentario y dejando una puntuación te damos las gracias.