#c# #wpf #xaml
#c# #wpf #xaml
Вопрос:
У меня есть некоторые, UserControl
они DataContext
привязаны к ViewModel, Как установить свойство ViewModel из XAML
? Возможно ли это?
UPD : Извините за то, что не очень понятно, я пытаюсь получить что-то вроде этого: DataContext UserControl привязан к ViewModel, мне нужно присвоить свойству ViewModel какое-то значение (скажем, свойству Width UserControl). Возможно ли это?
UPD2: Кажется, это невозможно.Я знаю о режиме привязки TwoWay и т.д., Что я хотел сделать — установить свойство ViewModel равным свойству UserControl
Этот пример должен быть очень понятным
<Set Property={Binding SomePropertyOnViewModel}
Value={Binding RelativeSource={RelativeSource Self},
Path=SomePropertyOnUserControl}>
Комментарии:
1. Учитывая опубликованный вами псевдо-XAML, почему <UserControl SomePropertyOnUserControl=»{Привязка SomePropertyOnViewModel, Mode=OneWayToSource}» /> не работает для вас? Чего именно вы хотите достичь (в увеличенном виде)?
2. Я хотел бы использовать привязку при определении свойства в UserControl, как в псевдо-xaml
3. вы можете выполнить привязку ко всем нужным свойствам DependencyProperties. итак, если ваш UserControl имеет какие-либо свойства DependencyProperties, вы можете привязаться к нему.
4. требование (или, скорее, необходимость) все еще не ясна. Вы хотите установить значение SomePropertyOnViewModel для определенного события? Можете ли вы опубликовать больше кода о том, чего вы хотите достичь?
Ответ №1:
Я не уверен, точно ли я понимаю вопрос.
Но вот пример. Это приведет:
-
Создайте модель представления типа
ExampleViewModel
внутри пользовательского элемента управления, установив свойство user controlsDataContext
в xaml -
Создайте текстовое поле в xaml и привяжите его к строковому свойству view models
TextInViewModel
. -
Настройте обычный
INotifyPropertyChanged
интерфейс (он был извлечен из базового классаViewModelBase
)
Создайте модель представления в xaml и задайте для нее контекст данных пользовательских элементов управления:
<UserControl x:Class="MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test"
xmlns:viewModel="clr-namespace:ViewModels">
<UserControl.DataContext>
<viewModel:ExampleViewModel/>
</UserControl.DataContext>
<StackPanel Orientation="Horizontal" >
<Label>Enter Text here: </Label>
<TextBox Text="{Binding TextInViewModel}"></TextBox>
</StackPanel>
</UserControl>
ViewModel:
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
}
public class ExampleViewModel : ViewModelBase
{
/// <summary>
/// Property bound to textbox in xaml.
/// </summary>
public String TextInViewModel
{
get { return _textInViewModel; }
set
{
_textInViewModel= value;
RaisePropertyChanged("TextInViewModel");
}
}
private string _textInViewModel;
/// <summary>
/// Constructor.
/// </summary>
public ExampleViewModel()
{
}
}
Ответ №2:
Привязка работает в обоих направлениях: т. е. от источника (например, viewmodel) к цели (например, usercontrol) и от цели обратно к источнику.
Вы указываете направление с помощью режима привязки.
Ниже приведены режимы привязки:
- TwoWay
- OneWay
- Одноразовый
- OneWayToSource
В вашем случае, если вы хотите привязать свойство width из usercontrol к свойству TheWidth ViewModel:
Случай A:
Хотите выполнить привязку в обоих направлениях, используйте Mode= TwoWay
<UserControl Width="{Binding TheWidth, Mode=TwoWay}">
<!-- your rest of code -->
</UserControl>
Случай B:
Хотите привязать к viewmodel только usercontrol, используйте Mode=OneWayToSource
<UserControl Width="{Binding TheWidth, Mode=OneWayToSource}">
<!-- your rest of code -->
</UserControl>
Комментарии:
1. да, я думал, это для silverlight, в wpf у вас есть onewaytosource, который является правильным ответом
Ответ №3:
XAML
<UserControl.DataContext>
<vm:ViewModel/>
</UserControl.DataContext>
Комментарии:
1. Хорошо, это установит DataContext для UserControl в new ViewModel(), так что …?
Ответ №4:
Я предпочитаю подход с локатором ViewModel (это похоже на шаблон поиска служб для ViewModel). Потому что, как только ваша ViewModel имеет параметры конструктора, вы либо тесно связаны, либо не можете использовать описанный выше способ xaml….
Существует множество способов определения местоположения ViewModel. Один из них описан здесь с использованием MEF и silverlight. http://johnpapa.net/simple-viewmodel-locator-for-mvvm-the-patients-have-left-the-asylum
вот еще один:http://brendan.enrick.com/post/Wire-up-your-ViewModels-using-a-Service-Locator.aspx
Ответ №5:
Ну, вы привязываете к ним свои элементы пользовательского интерфейса:
<UserControl Width="{Binding Path=DisplayWidth, Mode=OneWayToSource}">
<Grid>
<TextBox MinWidth=100 Text="{Binding MyProperty}"/>
</Grid>
</UserControl>
предполагая, что модель представления выглядит следующим образом:
class ViewModel
{
public string MyProperty { get; set; }
public int DisplayWidth { get; set; }
}
Комментарии:
1. Этот код привязывает что-то из UserControl к чему-то из ViewModel, проблема в том, что мне нужно, чтобы это было наоборот
2. Затем вы можете использовать Text=»{Привязка MyProperty, Mode=OneWayToSource}»
3. Нет, текст не является свойством ViewModel, смотрите мое описание в UPD
Ответ №6:
Через привязку, мой дорогой друг..
например: (предполагая в вашем контексте)
Если у вас есть класс «Person» и у вашего пользователя есть общедоступное свойство Name и FamIlyи вы хотите привязать его к текстовому полю. Вы делаете следующее:
<TextBox Text="{Binding Path=Name}" />
Это работает только в том случае, если имя является вашим общедоступным свойством, лучше всего сделать ваш объект (в данном случае Person) общедоступным свойством и использовать параметр Path по-другому.
Пример:
<TextBox Text="{Binding Path=Person.Name}" />
Это намного меньше загромождает ваш код, чем создание свойства в вашей viewmodel для каждого свойства любого объекта в вашей viewmodel.
Ответ №7:
«Как установить свойство ViewModel из XAML? Возможно ли это?»
Итак, это кажется невозможным, максимум, что вы можете выполнить — двусторонняя привязка, чего, к сожалению, я не хотел. В целом, это скорее плохой дизайн, чем проблема