La liaison UserControl Propriété de Dépendance et MVVM
J'ai une MainWindow contenant un UserControl, les deux mis en œuvre dans MVVM-modèle.
Le MainWindowVM a des propriétés que je veux lier aux propriétés de la UserControl1VM. Mais cela ne fonctionne pas.
Voici un code (le viewmodel utiliser une sorte de mvvm-cadre implémenter INotifyPropertyChanged dans un ViewModelBase de classe mais qui espérons-le, pas de problème):
MainWindow.xaml:
<Window x:Class="DPandMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DPandMVVM"
Title="MainWindow" Height="300" Width="300">
<Grid>
<local:UserControl1 TextInControl="{Binding Text}" />
</Grid>
</Window>
CodeBehind MainWindow.xaml.cs:
using System.Windows;
namespace DPandMVVM
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowVM();
}
}
}
MainWindow-ViewModel MainWindowVM.cs:
namespace DPandMVVM
{
public class MainWindowVM : ViewModelBase
{
private string _text;
public string Text { get { return _text; } }
public MainWindowVM()
{
_text = "Text from MainWindowVM";
}
}
}
Et ici le UserControl1.xaml:
<UserControl x:Class="DPandMVVM.UserControl1"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBlock Text="{Binding TextInTextBlock}" />
</Grid>
</UserControl>
Le Codebehind UserControl1.xaml.cs:
using System.Windows.Controls;
namespace DPandMVVM
{
///<summary>
///Interaction logic for UserControl1.xaml
///</summary>
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
DataContext = new UserControl1VM();
}
}
}
Et le Viewmodel UserControl1VM.cs:
using System.Windows;
namespace DPandMVVM
{
public class UserControl1VM : DependencyObject
{
public UserControl1VM()
{
TextInControl = "TextfromUserControl1VM";
}
public string TextInControl
{
get { return (string)GetValue(TextInControlProperty); }
set { SetValue(TextInControlProperty, value); }
}
public static readonly DependencyProperty TextInControlProperty =
DependencyProperty.Register("TextInControl", typeof(string), typeof(UserControl1VM));
}
}
Avec cette constellation le DP ne peut pas être trouvé dans MainWindow.xaml.
Ce que je fais mal?
Vous devez vous connecter pour publier un commentaire.
Première de tout ce que vous voulez DependencyProperty
TextInControl
être déclarée à l'intérieur d'UserControl1
si vous souhaitez lier à l'extérieur.Déplacer la déclaration de DP à l'intérieur de
UserControl1
.Deuxième vous avez à l'extérieur DataContext de UserControl à
UserControl1VM
,Donc WPF liaison moteur de recherche de biens immobiliers
Text
dansUserControl1VM
au lieu deMainWindowVM
. Supprimer le réglage de DataContext et mise à jour de XAML de UserControl1 à ceci:Lier DP à l'aide de
ElementName
par la mise enx:Name
sur UserControl.Mise à JOUR
Dans le cas où vous voulez avoir
ViewModel
intacte pourUserControl
, vous devez mettre à jour obligatoire dans MainWindow. Indiquer explicitement WPF moteur de liaison à regarder pour les biens en MainWindow du DataContext à l'aide deElementName
dans la liaison comme ceci:Pour cela, vous devez définir
x:Name="mainWindow"
sur la fenêtre au niveau de la racine.VM is supposed to contain only source properties whereas Target properties are defined at View level
commeTextInControl
qui est censé être défini à UserControl niveau. Et pour lier de MainWindow.xaml j'ai mis à jour la réponse, il devrait maintenant fonctionner. Je vous propose de lire plus de WPF liaison aperçu ici.How can I bind to the TextInTextBlock-Property of the UserControl-VM from the MainWindow.xaml?
- TextInTextBlock comme je l'ai mentionné dans le premier point doit être déclaré en tant que DP à l'intérieur de UserControl et non pas dans sa VM.Text
DP est déclarée à l'intérieur d'TextBox
à qui vous lier à certains biens dans votre VM à partir de XAML. C'est comment vous faites pour personnalisé DP est ainsi.You don't access DP's inside UserControl from VM
, mais que faire si il est plus complexe de communications UNIFIÉES mis en œuvre dans MVVM et j'ai besoin d'accéder à la DPs de la VM?Can you let me know where are you struggling in the posted question with the answer i provided?
N'est-il pas de travail pour petit échantillon que vous avez posté ici?TextInControl
dans l'UC de l'UC-VM.Le code XAML de votre commande dès maintenant référence à la propriété
TextInTextBlock
via le DataContext qui, à son tour "Points" de votre fenêtre principale du modèle de vue. De référence les données de la commande et vous avez terminé (btw, ne définissez pas le DataContext pour cette raison - la liaison ne fonctionne plus):J'ai une méthode que je crois que c'est beaucoup plus simple, et probablement plus vrai de MVVM.
Dans la fenêtre principale XAML:
Dans le modèle de vue (le contexte de données de la fenêtre principale:
maintenant, vous pouvez dans le constructeur (ou chaque fois que vous souhaitez instancier):
alors si vous souhaitez définir la propriété text:
et assurez-vous que vous avez la liaison de l'installation d'une propriété nommée Texte à l'intérieur de votre myUserControlViewModel classe:
et assurez-vous que la propriété des feux PropertyChanged, de-cours.
De Plus, si vous utilisez Resharper. Vous pouvez créer une instance de création de l'objet UserControl dans votre XAML de sorte qu'il peut lier les liaisons et de ne pas vous dire que la propriété n'est pas utilisée par le faire:
Cette partie:
C'est de cette façon je ne UserControls avec MVVM et DP de liaison. Il est similaire à Rohit de réponse, mais avec quelques légères modifications. Fondamentalement, vous devez définir le Contrôle interne du modèle de vue pour être le DataContext de la racine conteneur à l'intérieur de l'objet UserControl plutôt que de l'objet UserControl lui-même, de cette façon, il ne sera pas interférer avec DP liaisons.
E. g.
UserControl XAML
UserControl Code-behind
Cela signifie que le contrôle de la dérive, c'est les valeurs de l'élément Racine DataContext qui est notre ViewModel mais le ViewModel peut être mis à jour via une DP de liaison de l'extérieur de la de contrôle (dans votre cas, une liaison à la Fenêtre parent du ViewModel, voir ci-dessous)
Fenêtre XAML
Voici une possible solution de travail pour vous. Cependant, je l'ai noté dans un commentaire ci-dessus que cela fonctionnera dans le code et peut-être (comme mon cas) va apparaître comme une erreur (Objet Non Trouvé) dans le concepteur:
Je préfère avoir une solution plus propre, même si, sans aucun concepteur erreurs. Je voudrais savoir comment lier une propriété de dépendance dans un contrôle utilisateur à une valeur provenant de la fenêtre c'est contenue dans. Ce que je trouve est que tout ce que j'essaie de faire (à court de ce que j'ai montré ci-dessus), comme l'utilisation de ElementName et/ou AncestorType/Niveau, etc., le débogueur se plaint qu'il ne peut pas trouver la source et montre qu'il est à la recherche de la source à l'intérieur du contexte de l'utilisateur qui contrôle! C'est comme si je ne peux pas sortir de l'utilisateur de contrôler le contexte au moment de faire la Liaison logique dans l'utilisation de ce contrôle (autres que "concepteur-rupture" solution ci-dessus).
Mise à JOUR:
J'ai remarqué que cela pourrait ne pas fonctionner pour vous que votre situation sera peut-être un problème que je viens de remarquer que si je change mon propre source de référence de la fenêtre au lieu d'un contrôle qui a le contexte de données. Si je référence de la fenêtre, puis je finis avec une redondance cyclique. Peut-être que vous trouverez un moyen d'utiliser la version de la Source de la liaison qui fonctionne bien pour vous.
Je dois aussi ajouter que ma situation est sans doute un peu plus complexe, car mon usercontrol est utilisé dans le contexte d'une popup.