2016-09-13 7 views
0

У меня есть требование динамически загружать диаграмму (XAML, которая включает пользовательский UserControl, ScrewControl).Non XAML способ привязки данных к коллекции/словарь

Я рассматриваю способы привязки свойства зависимостей (Status) от ScrewControl от класса ViewModel. Задача состоит в том, что диаграмма может содержать различное количество ScrewControl s, каждая из которых должна быть привязана к словарю или коллекции в ViewModel.

Я решил первую задачу по загрузке XAML динамически с помощью XamlReader, но не уверен, как связать ScrewControl с помощью Collection/dictionary из ViewModel.

вид Модель Класс

public class AssemblyViewModel 
{ 
    public Dictionary<int, ScrewStatus> Screws { get; set; } 
    public FrameworkElement Image { get; set; } 

    ... 
} 

Просмотр класса

public partial class AssemblyView : UserControl 
{ 
    private AssemblyViewModel viewModel; 

    public AssemblyView(AssemblyViewModel viewModel) 
    { 
     InitializeComponent(); 
     DataContext = this.viewModel = viewModel; 

     Loaded += OnLoaded; 
    } 

    public FrameworkElement XamlContent 
    { 
     get { return (FrameworkElement)GetValue(XamlContentProperty); } 
     set { SetValue(XamlContentProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for Content. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty XamlContentProperty = 
     DependencyProperty.Register("XamlContent", typeof(FrameworkElement), typeof(AssemblyView), new PropertyMetadata(null, OnXamlChanged)); 

    private static void OnXamlChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) 
    { 
     var view = dependencyObject as AssemblyView; 
     var element = args.NewValue as FrameworkElement; 
     if (null != element) 
     { 
      view.ContentControl.Children.RemoveRange(0, 1); 
      view.ContentControl.Children.Add(element); 

      var screws = element.FindChildren<Screw>(); 

      try 
      { 
       foreach (var screw in screws) 
       { 
        // The ScrewControl has a name properties like "Screw_1", 1 is used as the key of the dictionary and Status as the Value 
        var parts = screw.Name.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries); 
        if (2 == parts.Length) 
        { 
         BindingOperations.SetBinding(
          screw, 
          Screw.ScrewStatusProperty, 
          new Binding(/*not sure what goes here*/) 
          { 
           Source = view.viewModel.Screws, 
          }); 
        } 
       } 
      } 
      catch (Exception e) 
      { 
       throw; 
      } 
     } 
    } 

    private void OnLoaded(object sender, RoutedEventArgs e) 
    { 

     // This works and loads the diagram 
     BindingOperations.SetBinding(
      this, 
      XamlContentProperty, 
      new Binding("Image") 
      { 
       Source = this.viewModel 
      }); 
    } 
+1

Чтобы иметь возможность ответить на это, нам нужно увидеть минимальную версию как Xaml, так и ViewModel –

ответ

0

Вы были почти там. Это должно работать:

foreach (var screw in screws) 
{ 
    // The ScrewControl has a name properties like "Screw_1", 1 is used as the key of the dictionary and Status as the Value 
    var parts = screw.Name.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries); 
    if (2 == parts.Length) 
    { 
     BindingOperations.SetBinding(
      screw, 
      Screw.ScrewStatusProperty, 
      new Binding() // No need for a path as we're going to bind directly to the source value 
      { 
       // The source of the databinding is the value of the Screws dictionary keyed by screw id (parsed from the screw name) 
       Source = view.viewModel.Screws[(int)parts[1]], 
      }); 
    } 
} 

Хотя это может быть более WPF'y ввернуть управления, загруженные из XAML публичной собственности и связать его как ItemsSource из в ItemsControl. Затем вы можете установить ItemTemplate как ContentControl со свойством Content, привязанным к ScrewStatus, и ContentTemplate привязанным к текущему элементу (т. Е. К пользовательскому управлению винтом, загруженному из XAML), что обеспечило бы более естественный способ привязки представления и модели вместе ,

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

  • Нет связанных вопросов^_^