2016-02-23 2 views
0

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

У меня есть ConnectorViewModel, который содержит класс FullyCreatedConnectorInfo, который хранит «опорную точку», где должен упасть узел. Для расчета этого я требую следующую функцию:.

public static Point GetPointForConnector(DesignerCanvas canvas, Connector source) 
{ 
    Point p = source.TranslatePoint(new Point(0, 0), canvas); 
    p.X += source.Width/2.0d; 
    p.Y += source.Height/2.0d; 
    return p; 
} 

Где разъем 'является UserControl точки подключения, DesignerCanvas является Canvas, который разъем находится в

Эта функция вызывается ConnectorViewModel к вычислить начальную и конечную точки кривых безье, привязанную к свойству из ConnectorViewModel.

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

Моя проблема в том, что если я хочу программно создать ConnectorViewModel, скажем MainWindow.xaml.cs Мне нужен доступ к коннектору и холсту. Я могу сделать что-то подобное для дизайнера холста:

<s:DesignerCanvas Loaded="DesignerCanvas_Loaded" 

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

Однако для соединителя это не так просто, как это определено с помощью шаблонов данных:

<DataTemplate DataType="{x:Type local:NodeViewModel}"> 
    <local2:Node/> 
</DataTemplate> 

Так что я не знаю, как я могу найти «узел» от «NodeViewModel».

Даже если бы я мог понять это, я не думаю, что это следует за MVVM правильно, так как ViewModel не должен знать, что в нем имеет элемент управления.

Если он соблюдает MVVM или делает это по-другому, это слишком сложно, и я должен сделать это таким образом, я хотел бы помочь в том, как это сделать?

код адаптирован из этого образца: http://www.codeproject.com/Articles/484616/MVVM-Diagram-Designer

ответ

0

Сообщение отсутствуют некоторые примеры кода, но от того, что я получаю, и по-моему, вы уже порывает MVVM при наличии Вашего GetPointForConnector() в ViewModel, так как вы ссылаясь на различные типы элементов пользовательского интерфейса. Являются ли опорные точки от FullyCreatedConnectorInfo взятыми из какой-то базы данных? Я бы поставил эти элементы на codebehind (т. Е. View.cs), чтобы правильно следовать MVVM. Если они были из базы данных, вы, вероятно, должны привязать опорные точки как объекты (а не элементы пользовательского интерфейса), имеющие простые double s, чтобы представлять координаты и обрабатывать их через конвертер на вашем представлении. Если они не из какой-то базы данных, то нет причин, по которым они должны быть на ViewModel, правильно?

Вам не нужно искать «Node» из «NodeViewModel». Это было бы признаком того, что вы нарушаете MVVM.

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

Что я имею в виду с помощью преобразователей:

Например, если вы хотите, чтобы отобразить точку на текстовое поле:

XAML:

<Grid.Resources> 
     <local:MultiConverter x:Key="multiconvert" ></local:MultiConverter> 
    </Grid.Resources> 
    <s:DesignerCanvas x:Name="DesignerCanvasName"> 
    <TextBox> 
     <TextBox.Text> 
      <MultiBinding Converter="{StaticResource multiconvert}"> 
       <Binding ElementName="DesignerCanvasName" Path="."/> 
       <Binding ElementName="ConnectorName" Path="."/> 
      </MultiBinding> 
     </TextBox.Text> 
    </TextBox> 

Преобразователь:

public class MultiConverter : IMultiValueConverter 
{ 

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     DesignerCanvas cavas = values[0] as DesignerCanvas; 
     Connector source= values[1] as Connector; 
     Point p = source.TranslatePoint(new Point(0, 0), canvas); 
     p.X += source.Width/2.0d; 
     // and so on 

    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

Проблема в том, что я не могу вычислить точку привязки линий без доступа к управлению холстом и узлом. – tweetypi

+0

@soshiki Любая причина, по которой вы не можете привязываться к преобразователю/мультиконвертеру? – Tyress

+0

Проблема заключается в том, что пути определяются как стиль в проекте DiagramDesigner, а холст - в MainWindow.xaml. Кроме того, фактические соединители определены в их собственном отдельном пользовательском элементе управления (Node.xaml) – tweetypi

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