У меня есть основной вид под названием MainContentView.xaml
, в котором я установил DataContext в ViewModel под названием MainContentViewModel.cs
. Здесь я могу обновить значения, которые появляются в пользовательском интерфейсе, так же, как нормальный MVVM будет работать.
Это выглядит следующим образом:Установить свойства в child UserControl текущего View с ViewModel (MVVM)
<UserControl x:Class="namespace:MyProject.View.Home.MainContentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UserTools="clr-namespace:MyProject.View.Tools"
xmlns:ViewModel="clr-namespace:MyProject.ViewModel.Home"
mc:Ignorable="d" >
<UserControl.DataContext>
<ViewModel:MainContentViewModel />
</UserControl.DataContext>
<Grid x:Name="mainGrid">
<!-- Normal objects -->
<StackPanel>
<Label Text="Im a label" />
<TextBox />
</StackPanel>
<!-- My Custom Object -->
<UserTools:MyCustomUserControl x:Name="myUserControl" />
</Grid>
</UserControl>
И мой MainContentViewModel.cs
выглядит следующим образом:
public class MainContentViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private string myLabel = "";
public string MyLabel {
get { return this.myLabel; }
set {
this.myLabel = value;
OnPropertyChangedEvent("MyLabel");
}
}
public MainContentViewModel() {
MyLabel = string.Format("my label text");
}
protected virtual void OnPropertyChangedEvent(string _propertyName) {
var _handler = this.PropertyChanged;
if(_handler != null) { _handler(this, new PropertyChangedEventArgs(_propertyName)); }
}
}
Теперь я хочу установить некоторые свойства в MyCustomUserControl.xaml
через его собственную MyCustomUserControlViewModel.cs
.
Мои MyCustomUserControl.xaml
выглядит следующим образом:
<UserControl x:Class="MyProject.View.Tools.MyCustomUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModel="clr-namespace:MyProject.ViewModel.Tools"
mc:Ignorable="d" >
<UserControl.DataContext>
<ViewModel:MyCustomUserControlViewModel />
</UserControl.DataContext>
<Grid x:Name="mainGrid">
<Label Content="{Binding myCustomLabel}" />
</Grid>
</UserControl>
И мой MyCustomUserControlViewModel.cs
выглядит следующим образом:
public class MyCustomUserControlViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private string myCustomLabel = "";
public string MyCustomLabel {
get { return this.myCustomLabel; }
set {
this.myCustomLabel = value;
OnPropertyChangedEvent("MyCustomLabel");
}
}
public MyCustomUserControlViewModel() {
MyCustomLabel = string.Format("my custom label text");
}
protected virtual void OnPropertyChangedEvent(string _propertyName) {
var _handler = this.PropertyChanged;
if(_handler != null) { _handler(this, new PropertyChangedEventArgs(_propertyName)); }
}
}
Теперь я хочу, из MainContentViewModel.cs
, обновите MyCustomLabel
недвижимости на MyUserCustomUserControl.xaml
, и я полагаю, я нужно сделать это через MyCustomUserControlViewModel.cs
, поэтому я могу сохранить шаблон MVVM.
Я пытался что-то вроде этого: В MainContentViewModel.cs
private MyCustomUserControlViewModel _viewModel = new MyCustomUserControlViewModel();
(...)
public MainContentViewModel() {
(...)
_viewModel.SetMyCustomLabel("my new custom label text");
}
И MyCustomUserControlViewModel.cs
public void SetMyCustomLabel(string _text) {
MyCustomLabel = _text;
}
Но это не работает. Я предполагаю, что это потому, что я создаю экземпляр другого объекта MyCustomUserControlViewModel.cs
.
Итак, как я могу это сделать?
ОБНОВЛЕНО И РАБОЧАЯ (Спасибо Sheridan)
Я взял один из решений Шеридана и в конечном итоге с этим рабочим раствором. В моих MainContentView.xaml
:
(...)
<UserTools:MyCustomUserControl DataContext="{Binding ChildViewModel, Mode=OneWay}" />
В моих MainContentViewModel.cs
:
private MyCustomUserControlViewModel childViewModel = new MyCustomUserControlViewModel();
public MyCustomUserControlViewModel ChildViewModel {
get { return childViewModel; }
private set { childViewModel = value; OnPropertyChangedEvent("ChildViewModel"); }
}
И тогда я могу это сделать:
public MainContentViewModel() {
(...)
ChildViewModel.SetMyCustomLabel("my new custom label text");
}
Когда вы указываете ' ' внутри DataTemplate, вы имеете в виду то же, что и 'x: Type ViewModels: MyCustom ...'? Кроме того, я не могу создать ChildViewModel в 'MainContentViewModel', как вы сказали. Что касается вашего последнего решения, я просто привел пример ярлыка в 'UserControl', объект намного сложнее, поэтому он отличается от' UserControl' и используется в нескольких местах. Это то, что я собрал из того, что вы сказали, по крайней мере. –
К сожалению, это была ошибка копирования/вставки, которую я сейчас исправил. Префикс пространства имен «Views» XML является префиксом для ваших представлений. «DataTemplate» просто устанавливает экземпляр вашего представления для отображения, когда экземпляр вашей модели просмотра найден в пользовательском интерфейсе. – Sheridan
Я понял, что вы говорили. Поэтому в основном я создаю «DataTemplate» дочернего представления с DataType моего дочернего ViewModel. Является ли объявление 'ChildViewModel' в' MainContentViewModel' правильным? И я полагаю, вам нужно связать его в представлении так: ' ', поэтому он не возвращает ошибку. –