Bindung UserControl Abhängigkeitseigenschaft und MVVM
Ich habe ein MainWindow mit einem UserControl, beide realisiert in MVVM-pattern.
Die MainWindowVM Eigenschaften hat, die ich will, um Bindungen an Eigenschaften im UserControl1VM. Aber das funktioniert nicht.
Hier ein paar Codes (die viewmodels verwenden irgendeine Art von mvvm-framework, implementiert die INotifyPropertyChanged-in eine ViewModelBase-Klasse, aber das ist hoffentlich kein problem):
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";
}
}
}
Und hier die 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>
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();
}
}
}
Und die 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));
}
}
Mit dieser Konstellation ist die DP nicht gefunden werden kann im MainWindow.xaml.
Was mache ich falsch?
InformationsquelleAutor joerg | 2014-03-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ersten der alles, was Sie wollen DependencyProperty
TextInControl
deklariert werden innerhalbUserControl1
wenn Sie möchten, binden Sie es von außen.Bewegen Sie die Erklärung von DP innerhalb der
UserControl1
.Zweiten Sie extern eingestellt DataContext des UserControl zu
UserControl1VM
,Also WPF binding engine der Suche nach einer Immobilie
Text
imUserControl1VM
stattMainWindowVM
. Entfernen Sie die Einstellung DataContext-und update-XAML des UserControl1:Binden DP mit
ElementName
durch Einstellungx:Name
auf UserControl.UPDATE
In Fall, dass Sie wollen, haben
ViewModel
intaktUserControl
Sie aktualisieren müssen, verbindlich im Hauptfenster. Explizit sagen, WPF binding engine zu suchen, Grundstück im Hauptfenster der DataContext mitElementName
verbindlich wie diese:Für diese müssen Sie
x:Name="mainWindow"
Fenster auf root-Ebene.Viewmodels jedenfalls sind nicht enthalten soll, EP. Sie sollte enthalten normalen CLR-Eigenschaften nur.
Stellen Sie sich das UserControl als "Black Box" für die anderen. Es ist nur eine Kontrolle, dass andere Benutzer verwenden, zu. Also wir haben einen Entwickler, der für die Kontrolle (das funktioniert in mvvm) und ein Entwickler für das Hauptfenster (das funktioniert in mvvm). Die Entwickler des MainWindow nur wollen, verwenden Sie die UserControl "leicht" und ohne zu wissen, details der Interna. Er will einfach nur zu binden, seine VM-Eigenschaften der DP des UserControl.
Und wie greife ich auf diese DP ' s in der UserControl aus der VM?
Sie nicht auf DP drin UserControl von VM. Sie binden mit jenen DP ' s. Wie
Text
ist DP deklariert innenTextBox
zu denen Sie eine Bindung zu bestimmten Eigenschaft in der VM von XAML. Das ist, wie Sie tun, für custom DP ist auch gut so.InformationsquelleAutor Rohit Vats
XAML Ihrer Kontrolle, jetzt die Eigenschaft verweisen
TextInTextBlock
über den DataContext die wiederum "Punkte" zu Ihrem Haupt-Fenster-Ansicht-Modell. Referenz die Daten der Kontrolle und Sie sind fertig (btw nicht DataContext aus diesem Grund - die Bindung funktioniert nicht mehr):InformationsquelleAutor gomi42
Dies ist, wie ich tun Benutzersteuerelemente mit MVVM und DP verbindlich. Es ist ähnlich wie Rohit Antwort, aber mit einigen geringfügigen änderungen. Im Grunde müssen Sie die Steuerung der internen view-Modell zu den DataContext der root-container innerhalb des UserControl anstatt das Benutzersteuerelement selbst, so wird es nicht stören mit DP-Bindungen.
E. g.
UserControl XAML
Benutzersteuerelement Code-behind -
Dies bedeutet, dass das Steuerelement, leitet es die Werte von dem Root-element DataContext, das ist unser ViewModel, aber das ViewModel aktualisiert werden kann, über eine DP-Bindung aus, die außerhalb der Kontrolle (in Ihrem Fall die Bindung an das übergeordnete Fenster ViewModel, siehe unten)
Fenster XAML
InformationsquelleAutor Neil Alderson
Hier ist eine mögliche funktionierende Lösung für Sie. Aber, ich habe bemerkte in einem Kommentar vor, dass dies funktioniert, im code und vielleicht (wie meine situation) wird zeigen, wie eine Fehlermeldung (Objekt Nicht Gefunden) im designer:
Ich würde eher auf eine saubere Lösung, allerdings ohne designer-Fehler. Ich möchte herausfinden, wie man richtig binden Sie eine Abhängigkeitseigenschaft in ein Benutzer-Steuerelement, um einen Wert aus dem Fenster, es ist auch enthalten in. Was ich zu finden bin ist, dass alles, was ich versuche zu tun (zu kurz, was ich oben zeigte), wie die Verwendung von ElementName und/oder AncestorType/Level etc., der debugger beschwert sich, dass es nicht finden können, die Quelle und zeigt, dass es sucht die Quelle, die innerhalb des Kontexts des Benutzer-Kontrolle! Es ist so, ich kann nicht brechen Sie aus der Benutzer-Steuerelement-Rahmen, wenn dabei die Bindung von Logik in die Verwendung von Steuern (andere als die "designer-breaking" - Lösung oben).
UPDATE:
Ich bemerkte, dass dies möglicherweise nicht für Sie arbeiten, wie Ihre situation erzwingen könnte ein problem ich habe gerade festgestellt, wenn ich meine eigene Quelle zu verweisen Fenster, anstatt ein Steuerelement, das Daten-Kontext. Wenn ich mich auf die Fenster, dann Ende ich mit einer zyklischen Redundanz. Vielleicht werden Sie herausfinden, einen Weg, um die Source-version von der Bindung, die die Arbeit für dich in Ordnung.
Ich muss auch hinzufügen, dass sich meine situation ist wohl etwas komplexer, da mein usercontrol verwendet wird, im Zusammenhang mit einem popup-Fenster.
InformationsquelleAutor Prethen
Habe ich eine Methode, die ich glaube, ist viel einfacher und wahrscheinlich mehr wahr zu MVVM.
In der Haupt-Fenster XAML:
In der main-view-model (den Daten-Kontext des Hauptfensters:
nun können Sie in den Konstruktor (oder Wann immer Sie wollen zu instanziieren):
dann, wenn Sie möchten, legen Sie die text-Eigenschaft:
und stellen Sie sicher, dass die verbindliche Einrichtung einer Eigenschaft namens Text in Ihrem myUserControlViewModel Klasse:
und stellen Sie sicher, dass die Eigenschaft " feuert PropertyChanged -, natürlich.
Plus, wenn Sie Resharper. Sie können erstellen Sie ein Design-Instanz des UserControl im XAML-Code, so dass Sie verknüpfen können, die Bindungen und nicht sagen Sie, dass die Eigenschaft wird nicht verwendet, dies zu tun:
Dieser Artikel:
InformationsquelleAutor phillk6751