Ich bin neu in WPF und MVVM. Derzeit wird eine WPF-Anwendung mit dem MVVM-Muster erstellt, die jedoch schnell mit mehreren MVVMs blockiert wurde.Binden Sie den DataContext eines UserControl zu einem Sub ViewModel
Grundsätzlich habe ich ein MainWindow und ein UserControl auf dem MainWindow. Es ist ein einfaches Benutzersteuerelement, das nur aus einer Bildsteuerung und einer Bildlaufleiste besteht. Wie unten dargestellt:
<UserControl x:Class="AutomaticContourEvaluation_WURO_WPF.Views.TwoDImageControl"
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"
xmlns:local="clr-namespace:AutomaticContourEvaluation_WURO_WPF.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding Path=CurrentSlice}" x:Name="sliceDisplayControl" />
<ScrollBar Grid.Column="1" Minimum="0" Maximum="{Binding Path=NumberOfSlices, FallbackValue=10}" Value="{Binding Path=SliceIndex, Mode=TwoWay, FallbackValue=0}" x:Name="sliceSelectionScrollBar" Margin="0,0,0,0"/>
</Grid>
Ansichtsmodell entspricht, ist so konzipiert, dass:
internal class TwoDSliceViewModel : INotifyPropertyChanged
{
private List<BitmapImage> _imageSlices;
private int _sliceIndex = 0;
public BitmapImage CurrentSlice { get { return _imageSlices[SliceIndex]; } }
public int NumberOfSlices { get { return _imageSlices.Count; } }
public int SliceIndex
{
get
{
return _sliceIndex;
}
set
{
if (_sliceIndex != value)
{
_sliceIndex = value;
NotifyPropertyChanged("SliceIndex");
NotifyPropertyChanged("CurrentSlice");
}
}
}
public TwoDSliceViewModel()
{
BitmapImage demoImage = new BitmapImage();
demoImage.UriSource = new Uri("2Ddemo.jpg", UriKind.Relative);
demoImage.CacheOption = BitmapCacheOption.OnLoad;
if (_imageSlices == null)
{
_imageSlices = new List<BitmapImage>();
}
_imageSlices.Add(demoImage);
}
public TwoDSliceViewModel(List<BitmapImage> imageSlices)
{
_imageSlices = imageSlices;
}
public void updateImageSlices(List<BitmapImage> images)
{
_imageSlices = images;
_sliceIndex = 0;
NotifyPropertyChanged("CurrentSlice");
NotifyPropertyChanged("NumberOfSlices");
NotifyPropertyChanged("SliceIndex");
}
#region INotifyPropertyChanged Methods
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
In meinem MainWindowViewModel gibt es eine Instanz der TwoDSliceViewModel:
internal class MainWindowViewModel:INotifyPropertyChanged
{
...
private TwoDSliceViewModel _twoDSliceViewModel = new TwoDSliceViewModel();
public TwoDSliceViewModel TwoDModuleViewModel { get { return _twoDSliceViewModel; } }
...
}
Um Um die Arbeit von UserControl (TwoDSliceControl) zu binden, richte ich den DataContext des UserContro ein l in meinem MainWindow.xaml wie unten:
<Window ...>
<Window.DataContext>
<viewModel:MainWindowViewModel />
</Window.DataContext>
...
<control:TwoDImageControl x:Name="twoDSliceImageControl" DataContext="{Binding Path=TwoDModuleViewModel}" />
...
</Window>
Mein Usercontrol (TwoDSliceControl) ist Ansichtsmodell spezifisch, so dass ich wähle diese Art und Weise statt Abhängigkeitseigenschaften verwenden. Aber die Bindung ist fehlgeschlagen. Sie konnten in meinem Code sehen, dass ich bei der Instanziierung des TwoDSliceViewModels einige Demo-Daten erstellt habe, diese Dummy-Daten jedoch nicht angezeigt werden.
Ich habe Haltepunkte verwendet, um herauszufinden, dass Nachdem der MainWindow erfolgreich initialisiert wurde, ist der DataContext des TwoDSliceControl gut eingestellt. Die Source-Eigenschaft von ImageControl in der TwoDSliceControl- und der MaxValue-Eigenschaft der ScrollBar in dem TwoDSliceControl sind jedoch null.
Ich habe das Gefühl, dass diese Linie des XAML-Code:
<control:TwoDImageControl x:Name="twoDSliceImageControl" DataContext="{Binding Path=TwoDModuleViewModel}" />
die twoDSliceImageControl ersten tatsächlich initialisieren und dann die twoDSliceImageControl.DataContext Eigenschaft festgelegt. Nach der Initialisierung ist der Parameter twoDSliceImageControl.DataContext gleich null, sodass die Bindung innerhalb von twoDSliceImageControl fehlschlägt. Obwohl nach der Initialisierung der twoDSliceImageControl.DataContext gut eingestellt ist, werden Bindungen innerhalb des UserControl nicht aktualisiert, und sie sind immernoch null.
Jede Problemumgehung, um dieses Problem zu lösen? Ich war eine Weile darauf und habe keine richtige Lösung gefunden. Danke Leute!
Ihr Code sollte auf den ersten Blick funktionieren. Wie weisen Sie MainWindowViewModel dem DataContext Ihres Fensters zu, das die Steuerung enthält: TwoDImageControl? –
@AntonDanylov Ich habe meinen Beitrag aktualisiert, um die Zuordnung von MainWindowViewModel widerzuspiegeln. –
Fügen Sie die Diagnose von diesem Beitrag http: // stackoverflow hinzu.com/questions/337023/how-to-detect-broken-wpf-Datenbindung an Ihre DataContext-Bindung und es wird Ihnen sagen, wie es die Werte nachschlagen und was die Werte sind. – user3690202