2015-06-18 3 views
1

Без нарушения MVVM существует ли способ показать некоторые свойства дочернего элемента управления в пользовательском элементе управления, чтобы окно или другой пользовательский элемент управления, который использует его, могли получить доступ к этим свойствам напрямую?Выводить дочерние свойства пользовательского элемента управления непосредственно как свойство пользовательского элемента управления

Например, у меня есть пользовательский элемент управления, который имеет listview, настроенный с помощью gridviewcolumns, заголовков и привязан к модели представления. Но в представлении списка в элементе управления пользователя были выбраны свойства элемента и такие, что я хотел бы выставить на хост без необходимости делать что-то вроде usercontrol.customListView.property. Или так я должен это делать? Я бы хотел просто запустить usercontrol.property, не указав customListView. Perhap Мне нужно просто создать свойства в коде управления пользователя, за которым возвращаются свойства управления списком, которые я хочу привязать непосредственно к пользовательскому элементу управления?

Я чувствую, что этот последний вариант действительно не нарушает MVVM, поскольку они выставлены для хоста, чтобы взаимодействовать с ним, а не действительно касались самого представления. Любые предлагаемые оценки будут оценены.

EDIT: На самом деле, я бы очень хотел иметь свойство SelectedItem непосредственно на пользовательский элемент управления, который не ListViewItem или объект, но на самом деле от типа данных содержал, что лань, как:

public MyDataType SelectedItem { 
    get { 
     return customListView.SelectedItem as MyDataType; 
    } 
} 

бы, допустимо в MVVM? Поскольку я не вижу, как это возможно в ViewModel, похоже, что это должно быть в частичном коде класса.

+1

Просто добавьте DepandencyProperty на свой контроль и привяжите его/переустановите его ('Binding RelativeSource {FindAncestor}') на дочернем элементе управления (btw и, возможно, OT, .columns на WPF datagrid не могут быть связаны). Cant видит какие-либо проблемы с MVVM - скажем, ComboBox использует другие элементы управления, и у вас нет проблем с его использованием в MVVM :) –

+0

Этот вопрос не имеет ничего общего с MVVM. – Sheridan

+0

«У меня есть пользовательский элемент управления, который имеет список, настроенный с помощью gridviewcolumns, headers ** и привязан к модели представления. **« Да, вот почему у вас проблемы. У вас не должно быть ЛЮБЫХ ViewModels внутри вашего UserControl. Вы должны выставлять свойства на поверхности для всего, что вам нужно, а затем привязывать дочерние элементы UC к этим свойствам. Если вам нужно выполнить логику пользовательского интерфейса в своем UC, используйте код. Не создавайте виртуальную машину, предназначенную для использования внутри UC. Имеет ли TextBox TextBoxViewModel? Нет. Относитесь к своему UC как к Control, а не к подмножеству логики. – Will

ответ

2

Это довольно распространенная задача, когда вы хотите что-то повторить в UserControl. Самый простой способ сделать это - это когда вы не создаете специализированный ViewModel для этого UserControl, но вроде делаете пользовательский контроль (для простоты постройте с помощью UserControl). Конечный результат может выглядеть следующим образом:

<UserControl x:Class="SomeNamespace.SomeUserControl" ...> 
    ... 
    <TextBlock Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}" ...> 
</UserControl> 

.

public partial class SomeUserControl : UserControl 
{ 
    // simple dependency property to bind to 
    public string Text 
    { 
     get { return (string)GetValue(TextProperty); } 
     set { SetValue(TextProperty, value); } 
    } 
    public static readonly DependencyProperty TextProperty = 
     DependencyProperty.Register("Text", typeof(string), typeof(SomeUserControl), new PropertyMetadata()); 

    // has some complicated logic 
    public double Value 
    { 
     get { return (double)GetValue(ValueProperty); } 
     set { SetValue(ValueProperty, value); } 
    } 
    public static readonly DependencyProperty ValueProperty = 
     DependencyProperty.Register("Value", typeof(double), typeof(SomeUserControl), 
     new PropertyMetadata((d, a) => ((SomeUserControl)d).ValueChanged())); 
    private void ValueChanged() 
    { 
     ... // do something complicated here 
      // e.g. create complicated dynamic animation 
    } 

    ... 
} 

использование будет выглядеть следующим образом в сдерживании окна

<l:SomeUserControl Text="Text" Value="{Binding SomeValue}" ... /> 

Как вы можете видеть SomeValue обязаны Value и нет никаких нарушений MVVM.

Конечно, вы можете создать надлежащий ViewModel, если логика просмотра сложна или требуется слишком много привязок, и проще, если ViewModels напрямую связывается (через свойства/методы).

+0

Существует обычная логика с представлением, которое происходит в модели представления. Например, я работаю над списком с различными столбцами типа данных компании. Я расширяю BindableBase от Prism и обычно использую SetProperty() для установки свойств там, где это возможно. Вы знаете, если SetProperty автоматически регистрирует DependencyProperty от имени класса, если он еще не зарегистрирован? Также я хочу напрямую разоблачить SelectedItem как тип компании и выставить событие SelectionChanged для типа компании. – steviesama

Смежные вопросы

 Смежные вопросы