Pergunta

I have a view with couple of data templates in the resources of that view. (I don't want to put it somewhere global since its only needed by this particular view)

Based on value I get in converter I switch the template.

public class SplitTemplateSelector : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int splitCount = (int)value;
            var _view = new IdtDetailView();

            DataTemplate template;
            if (splitCount == 1)
            {
                //(DataTemplate)_view.Resources["SingleSplitTemplate"];
                template = (DataTemplate)_view.Resources.Where(w => w.Key.Equals("SingleSplitTemplate")).FirstOrDefault().Value;
            }
            else
            {
                template = (DataTemplate)_view.Resources.Where(w => w.Key.Equals("MultiSplitTemplate")).FirstOrDefault().Value;
            }

            return template;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }

This works as intended, however because I instantiate new IdtDetailView(), I run into some problems where variables aren't set-up properly etc. Therefore my question is...

How do I pass or access view which called this converter so that I don't have to create new IdtDetailView?

Foi útil?

Solução

I suggest next solution:

 public class SplitTemplateSelector : DependencyObject, IValueConverter
    {
        public static readonly DependencyProperty SingleSplitTemplateProperty =
            DependencyProperty.Register("SingleSplitTemplate",
                                        typeof (DataTemplate),
                                        typeof(SplitTemplateSelector),
                                        null);

        public DataTemplate SingleSplitTemplate
        {
            get { return (DataTemplate) GetValue(SingleSplitTemplateProperty); }
            set { SetValue(SingleSplitTemplateProperty, value); }
        }

        public static readonly DependencyProperty MultiSplitTemplateProperty =
            DependencyProperty.Register("MultiSplitTemplate",
                                        typeof (DataTemplate),
                                        typeof(SplitTemplateSelector),
                                        null);

        public DataTemplate MultiSplitTemplate
        {
            get { return (DataTemplate) GetValue(MultiSplitTemplateProperty); }
            set { SetValue(MultiSplitTemplateProperty, value); }
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int splitCount = (int)value;
            return splitCount == 1 ? SingleSplitTemplate : MultiSplitTemplate;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }

    }

In XAML:

<c:SplitTemplateSelector x:Key="SplitTemplateSelector" SingleSplitTemplate="{StaticResource SingleSplitTemplate}" MultiSplitTemplate="{StaticResource MultiSplitTemplate}"/>

As you understand, you can put converter near local data templates in user control resources

Outras dicas

Sounds like you need some kind of DataTemplateSelector. Unfortunately, this class only exists in WPF but you can find some alternative implementations on the web. For example: http://skysigal.xact-solutions.com/Blog/tabid/427/entryid/1404/Silverlight-a-port-of-the-DataTemplateSelector.aspx

The idea is to have a content control that has an array of data templates. The selection of the displayed content is based on a value (in your case it's an integer).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top