2016-02-10 3 views
1

Я работаю на UserControl, где я TreeView основанный на пользовательском классе, построить так:Изменен DataContext. Как правильно выполняют Binding

-ConnectionModel

--- SchemaModel

----- SchemaCollection

------- TableModel

TreeView работает как шарм.

Я добавил ContextMenu после нажатия на элемент TableModel в TreeView. Затем я хочу создать привязку к команде «SelectFromTab», которую я объявляю в классе SideBar() (который является ModelView для этого представления).

Как должным образом сделать привязку к команде SelectFromTab в классе SideBar? Теперь DataContext ContextMenu установлен в «TableModel».

My View (полный .xaml)

<Page 
    .... 
    xmlns:local="clr-namespace:ProgDB4.ViewModel" 
    xmlns:models="clr-namespace:ProgDB4.Model" 

    xmlns:ProgDB4="clr-namespace:ProgDB4" x:Name="page" x:Class="ProgDB4.ViewModel.SideBar" 

    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="300" 
    Title="SideBar"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition/> 
     <RowDefinition Height="20"/> 
    </Grid.RowDefinitions> 
    <TabControl Grid.Row="0" x:Name="SideBarTabControl" SelectionChanged="SideBarTabControl_SelectionChanged"> 
     <TabItem Header="Map" Content="Mapa"/> 
     <TabItem Header="History" Content="History"/> 
     <TabItem Header="Aliases" x:Name="tab_aliases" Width="52"> 
      <Grid> 
       <TreeView x:Name="AliasTree" ItemsSource="{Binding TVData}"> 
        <TreeView.Resources > 
         <HierarchicalDataTemplate DataType="{x:Type models:ConnectionModel}" ItemsSource="{Binding schemas}"> 
          <TextBlock Text="{Binding alias}" /> 
         </HierarchicalDataTemplate> 

         <HierarchicalDataTemplate DataType="{x:Type models:SchemaModel}"  ItemsSource="{Binding schema_collections}"> 
          <TextBlock Text="{Binding SCHEMA_NAME}" /> 
         </HierarchicalDataTemplate> 


         <HierarchicalDataTemplate DataType="{x:Type models:SchemaCollection}" ItemsSource="{Binding collection}"> 
          <TextBlock Text="{Binding SCHEMA_COLLECTION_NAME}" /> 
         </HierarchicalDataTemplate> 

         <DataTemplate DataType="{x:Type models:TableModel}" > 
          <TextBlock Text="{Binding TABLE_NAME}" PreviewMouseRightButtonDown="TextBlock_PreviewMouseRightButtonDown" > 

           <TextBlock.ContextMenu> 
            <ContextMenu> 
             <MenuItem Header="SELECT TOP 100" Command ="{Binding SelectFromTab}"/> 
             <MenuItem Header="SELECT TOP 1000"/> 
             <MenuItem Header="Display indexes"/> 
             <MenuItem Header="Display columns"/> 
            </ContextMenu> 
           </TextBlock.ContextMenu> 

          </TextBlock> 
         </DataTemplate> 
        </TreeView.Resources> 
       </TreeView> 

      </Grid> 
     </TabItem> 
    </TabControl> 
    <TextBox x:Name="SearchBox" Text="Search..." Height="20" Grid.Row="1" TextChanged="SearchBox_TextChanged" GotFocus="SearchBox_GotFocus" LostFocus="SearchBox_LostFocus"/> 
</Grid> 

Мой SideBar класс:

public partial class SideBar : Page, INotifyPropertyChanged 
{ 
    private List<ConnectionModel> _TVData; 
    public MainViewModel mainViewModelContext; 
    public TreeView tmpAliasTree = new TreeView(); 

    public ICommand _SelectFromTab; 
    public ICommand SelectFromTab 
    { 
     get 
     { 
      MessageBox.Show("ddd"); 
      return _SelectFromTab; 

     } 
     set { if (value != _SelectFromTab) { _SelectFromTab = value; } } 
    } 

    public SideBar(MainViewModel mainViewContext) 
    { 
     TreeViewBase = new List<ConnectionModel>(ConnectionUtilities.LoadObservableConnections()); 
     mainViewModelContext = mainViewContext ; 

     InitializeComponent(); 

     this.DataContext = this ; 

     // this.SelectFromTab = mainViewModelContext.SelectFromTab ; 

     var loadSideBar = Task.Factory.StartNew(async() => { await LoadSideBar(); }); 
     loadSideBar.Wait(); 

     OnPropertyChanged("TVData"); 
    } 

ответ

1

ContextMenu не получает такой же DataContext как ваш UserControl. Вы можете установить его вручную.

private void ContextMenu_Loaded(object sender, RoutedEventArgs e) 
    { 
     (sender as FrameworkElement).DataContext = this; 
    } 

и ваша команда будет работать нормально.

0

Как я понимаю, проблема заключается в связывании команду Контекстное меню элемент TableModel в его родительскую (UserControl) команду DataContext «SelectFromTab». Если это так, вам нужно выполнить привязку RelativeSource, когда режим привязки - FindAncestor. Но вот небольшая проблема, ContextMenu не существует в визуальном дереве элемента TabModel. См. Следующий пример в качестве отправной точки для ваших исследований.

XAML

<Style TargetType="SetHereTheTypeOfDataContextMenyTargetControl"> 
     <Setter Property="dataGridCreateColumnAndBindIteFromCodeBehind:Attached.ParentDataContextToTag" Value="True"></Setter> 
     <Setter Property="ContextMenu"> 
      <Setter.Value> 
       <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"> 
        <MenuItem Header="MenuItem One" 
           Command="{Binding CmdMenuItemOne}" /> 
        <MenuItem Header="MenuItem Two" 
           Command="{Binding CmdMenuItemTwo}" /> 
       </ContextMenu> 
      </Setter.Value> 
     </Setter> 
    </Style> 

код Attached Property

public class Attached 
{ 

    public static readonly DependencyProperty SetDataGridDataContextToTagProperty = DependencyProperty.RegisterAttached(
     "SetDataGridDataContextToTag", typeof (bool), typeof (Attached), new PropertyMetadata(default(bool), SetParentDataContextToTagPropertyChangedCallback)); 

    public static void SetSetDataGridDataContextToTag(DependencyObject element, bool value) 
    { 
     element.SetValue(SetDataGridDataContextToTagProperty, value); 
    } 

    public static bool GetSetDataGridDataContextToTag(DependencyObject element) 
    { 
     return (bool) element.GetValue(SetDataGridDataContextToTagProperty); 
    } 

    private static void SetParentDataContextToTagPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) 
    { 
     PerformDataContextToTagAssignment(dependencyObject as FrameworkElement, (bool)args.NewValue); 
    } 

    private static void PerformDataContextToTagAssignment(FrameworkElement sender, bool isAttaching) 
    { 
     var control = sender; 
     if (control == null) return; 
     if (isAttaching == false) 
     { 
      control.Tag = null; 
     } 
     else 
     { 
      var dataGrid = control.FindParent<PutHereTheTypeOfVisualParentWhichDataContextYouNeed>(); 
      if (dataGrid == null) return; 
      control.Tag = dataGrid.DataContext; 
     } 
    } 
} 

код Helper в

public static class VisualTreeHelperExtensions 
{ 
    public static T FindParent<T>(this DependencyObject child) where T : DependencyObject 
    { 
     while (true) 
     { 
      //get parent item 
      DependencyObject parentObject = VisualTreeHelper.GetParent(child); 

      //we've reached the end of the tree 
      if (parentObject == null) return null; 

      //check if the parent matches the type we're looking for 
      T parent = parentObject as T; 
      if (parent != null) 
       return parent; 
      child = parentObject; 
     } 
    } 
} 

Позвольте мне кп Если вам нужна помощь с кодом или.

С уважением.

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

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