Что делать с диаграммами, которые не поддерживают привязку? - PullRequest
1 голос
/ 21 декабря 2011

Я работаю с инструментом построения диаграмм, который не поддерживает привязку в смысле mvvm.Итак, я решил, что буду использовать своего рода службу обмена сообщениями (например, среду обмена сообщениями MVVM Light), чтобы каждый раз, когда обновляется viewmodel observablecollection, отправлялось сообщение, которое при получении добавляет точки данных в диаграмму (это будетв коде позади, к сожалению).Ребята, вы видите какие-либо проблемы с этим планом?

Ответы [ 2 ]

1 голос
/ 21 декабря 2011

Лично я считаю, что обмен сообщениями - это слишком много для того, чего вы пытаетесь достичь, хотя и по вкусу. Разве вы не можете использовать Адаптер или прикрепленные образцы поведения? Это то, что они обычно используют для замены отсутствующего функционала. Если вы можете создать свою диаграмму в Xaml (что, я надеюсь, у вас получится), я бы порекомендовал использовать присоединенное поведение, в противном случае использовать и apater (для элементов, которые не имеют открытых конструкторов или каких-либо других хитрых вещей) и создавать его в коде. .

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

Код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public Dictionary<int, int> MyValues
        {
            get
            {
                return Enumerable.Range(1, 3).ToDictionary(k => k, v => v);
            }
        }
    }

    // component with the 'missing' property
    public class Imperative : FrameworkElement
    {
        public void Add(int x, int y)
        {
            MessageBox.Show(string.Format("{0}_{1}", x, y));
        }
    }

    // compensating behavior
    public class DeclarativeBehavior : DependencyObject
    {
        public static DependencyProperty MissingPropertyProperty =
            DependencyProperty.RegisterAttached("MissingProperty",
            typeof(Dictionary<int, int>),
            typeof(DeclarativeBehavior),
            new PropertyMetadata((o, e) => 
            { 
                //
                Imperative imperative = (Imperative)o;
                Dictionary<int, int> values = (Dictionary<int, int>)e.NewValue;


                if (imperative != null)
                {
                    foreach (KeyValuePair<int, int> value in values)
                    {
                        imperative.Add(value.Key, value.Value);
                    }
                }
            }));

        public static void SetMissingProperty(DependencyObject o, Dictionary<int, int> e)
        {
            o.SetValue(DeclarativeBehavior.MissingPropertyProperty, e);
        }

        public static Dictionary<int, int> GetMissingProperty(DependencyObject o)
        {
            return (Dictionary<int, int>)o.GetValue(DeclarativeBehavior.MissingPropertyProperty);
        }
    }
}

1008 * XAML *

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <!--black box, which supports imperative calls is extended to support declarative calls too-->
        <local:Imperative local:DeclarativeBehavior.MissingProperty="{Binding MyValues, 
            RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
    </Grid>
</Window>
0 голосов
/ 21 декабря 2011

Рассматривали ли вы внедрение своего представления в ViewModel с использованием интерфейса для поддержания разделения? Я знаю, что это нарушает MVVM, но я успешно использовал это в ряде проектов WPF. Я называю это MiVVM или модель с интерфейсом для просмотра ViewModel .

Шаблон прост. Ваш Usercontrol должен иметь интерфейс, назовите его IView. Затем в ViewModel у вас есть свойство с установщиком типа IMyView, скажем

public IMyView InjectedView { set { _injectedView = value; } }

Затем в представлении вы создаете свойство зависимости с именем This

.
public MyUserControl : IMyView
{
    public static readonly DependencyProperty ThisProperty = 
         DependencyProperty.Register("This", typeof(IMyView), typeof(MyUserControl)); 

    public MyUserControl() 
    {
       SetValue(ThisProperty, this);
    } 
    public IMyView This { get { return GetValue(ThisProperty); } set { /* do nothing */ } } 
}

наконец, в Xaml вы можете внедрить представление непосредственно в ViewModel, используя привязку

<MyUserControl This="{Binding InjectedView, Mode=OneWayToSource}"/>

Попробуйте! Я использовал этот шаблон много раз, и вы получаете интерфейс к представлению, внедренному один раз при запуске. Это означает, что вы поддерживаете разделение (Viewmodel можно протестировать, так как IView можно смоделировать), но вы обошли отсутствие поддержки связывания во многих сторонних элементах управления. Плюс, это быстро. Знаете ли вы, связывание использует отражение?

Наконец, я реализовал элемент управления диаграммой, который использует этот шаблон для поддержки MVVM на ABT Software Services при сохранении высокопроизводительного программного API. компонент диаграммы называется SciChart , в котором используется рендеринг в непосредственном режиме и оптимизация нескольких чертежей для создания диаграмм с очень высокой производительностью для научных / финансовых приложений.

Существует демонстрационный проект, демонстрирующий этот шаблон в ссылке на блог выше. Я бы рекомендовал опробовать реализацию MiVVM с присоединенным свойством, если вы используете сторонний контроль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...