2009-11-12 16 views
8

मेरे पास एक WPF TreeView नियंत्रण के शीर्ष पर एक व्यूमोडेल है। मैं ViewModel को TreeView से चयनित इटैम सेट और पढ़ने में सक्षम होना चाहता हूं। हालांकि, TreeView की चयनित इटैम संपत्ति बाध्यकारी नहीं है।व्यू मॉडल में चयनित दृश्य में ट्री व्यू सिंक

मैं कोड के पीछे कोड में आइटम को सेट करने और प्राप्त करने में सक्षम हूं (ItemContainerGenerator और TreeViewItem.IsSelected = true) का उपयोग करके, लेकिन इससे पीछे कोड और व्यूमोडेल के बीच कुछ बदसूरत संचार होता है।

क्या किसी के पास इसका साफ समाधान है?

+1

क्या आपने कभी इसे हल किया था? मेरे पास वास्तव में यह मुद्दा है। – BrettRobi

+3

मुझे लगता है कि यह प्रश्न का डुप्लिकेट है http://stackoverflow.com/questions/1000040/selecteditem-in-a-wpf-treeview –

उत्तर

0

आप अपने ViewModel करने के लिए SelectedItem संपत्ति बाध्य करने के लिए संपत्ति और बाहर संपत्ति बाँध में प्रॉक्सी वर्ग किसी तरह का उपयोग कर सकते हैं:

public class Proxy : FrameworkElement 
    { 
    public static readonly DependencyProperty InProperty; 
    public static readonly DependencyProperty OutProperty; 

    public Proxy() 
    { 
     Visibility = Visibility.Collapsed; 
    } 

    static Proxy() 
    { 
     var inMetadata = new FrameworkPropertyMetadata(
      delegate(DependencyObject p, DependencyPropertyChangedEventArgs args) 
       { 
        if (null != BindingOperations.GetBinding(p, OutProperty)) 
        { 
         var proxy = p as Proxy; 
         if (proxy != null) 
          proxy.Out = args.NewValue; 
        } 
       }); 

     inMetadata.BindsTwoWayByDefault = false; 
     inMetadata.DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 

     InProperty = DependencyProperty.Register("In", 
               typeof (object), 
               typeof (Proxy), 
               inMetadata); 

     var outMetadata = new FrameworkPropertyMetadata(
      delegate(DependencyObject p, DependencyPropertyChangedEventArgs args) 
       { 
        ValueSource source = DependencyPropertyHelper.GetValueSource(p, args.Property); 

        if (source.BaseValueSource != BaseValueSource.Local) 
        { 
         var proxy = p as Proxy; 
         if (proxy != null) 
         { 
          var expected = proxy.In; 
          if (!ReferenceEquals(args.NewValue, expected)) 
          { 
           Dispatcher.CurrentDispatcher.BeginInvoke(
            DispatcherPriority.DataBind, new Action(delegate 
                       { 
                        proxy.Out = proxy.In; 
                       })); 
          } 
         } 
        } 
       }); 

     outMetadata.BindsTwoWayByDefault = true; 
     outMetadata.DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 

     OutProperty = DependencyProperty.Register("Out", 
                typeof (object), 
                typeof (Proxy), 
                outMetadata); 
    } 

    public object In 
    { 
     get { return GetValue(InProperty); } 
     set { SetValue(InProperty, value); } 
    } 

    public object Out 
    { 
     get { return GetValue(OutProperty); } 
     set { SetValue(OutProperty, value); } 
    } 
} 
<Proxy In="{Binding ElementName=Tree, Path=SelectedItem}" Out="{Binding SelectedItem, UpdateSourceTrigger=PropertyChanged}"/> 
<TreeView x:Name="Tree" ItemsSource="{Binding Path=Items}"/> 
1

मैं एक उदाहरण दे सकता है। मैं क्या करता हूं IsSelectedTreeViewItem (TreeView स्वयं नहीं) दृश्य मॉडल में, क्योंकि आप इससे जुड़ सकते हैं।

मेरे विचार मॉडल में मेरे पास एक संपत्ति ElementInViewModel है जो एक डेटा संरचना है जो एक पेड़ बनाती है। मैं इसे प्रदर्शित करने के लिए अपने Xaml में HierarchicalDataTemplate का उपयोग करता हूं। डेटा ऑब्जेक्ट स्वयं YourDomainType प्रकार का है और इसके बच्चे तत्व (उसी प्रकार के) ChildElements संपत्ति में हैं।

दृश्य मॉडल में, मैंने IsExpanded और IsSelected मेरी डेटा क्लास YourDomainType की संपत्ति सेट की है। नीचे परिभाषित शैली की वजह से, वे इस सेटिंग को TreeViewItem पर पास कर देंगे।

क्या यह आपके लिए काम करता है?

<UserControl> 

    <UserControl.Resources>   
     <CollectionViewSource Source="{Binding Path=ElementInViewModel}" x:Key="Cvs"> 
     </CollectionViewSource> 

     <HierarchicalDataTemplate DataType="{x:Type DomainModel:YourDomainType}" 
            ItemsSource="{Binding Path=ChildElements}"> 
      <TextBlock Text="{Binding Path=Name}"/>    
     </HierarchicalDataTemplate>   

     <Style TargetType="{x:Type TreeViewItem}"> 
      <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
      </Setter> 
      <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
      </Setter>    
     </Style> 

    </UserControl.Resources> 


    <DockPanel> 
     <TreeView ItemsSource="{Binding Source={StaticResource Cvs}}"/> 
    </DockPanel> 

</UserControl> 
संबंधित मुद्दे