Cómo habilitar/deshabilitar el elemento del menú (en el menú contextual) para un elemento seleccionado de la vista de árbol

Necesito usar un control de vista de árbol en la aplicación WPF. Creo datos anidados (con tipo DataItem) y los asigno al control de vista de árbol. Cree una plantilla de datos jerárquicos y asígnela al control de vista de árbol. Agregue un menú contextual a la vista de árbol. Ahora quiero deshabilitar o habilitar el elemento de menú mediante una propiedad de Elemento seleccionado (creo que debería ser Elemento de datos), "IsEnabled"

¿Cómo abordar eso?

            <HierarchicalDataTemplate x:Key="dt" ItemsSource="{Binding Items}">
                <TextBlock x:Uid="TextBlock_2" Text="{Binding Name}">
                </TextBlock>
            </HierarchicalDataTemplate>

        <TreeView x:Name="tree_3" Height="200"
                  ItemTemplate="{StaticResource dt}"
                  >
            <TreeView.ContextMenu>
                <ContextMenu>
                    <MenuItem ItemsSource="{Binding SelectedItem}"
                        Header="doA" IsEnabled="{Binding IsEnabled, Mode=OneWay}"  />
                    <MenuItem Header="doB" IsEnabled="False"/>
                    <MenuItem Header="doC" />
                </ContextMenu>
            </TreeView.ContextMenu>
        </TreeView>

class DataItem : DependencyObject //INotifyPropertyChanged
{
    private List<DataItem> _items = new List<DataItem>();
    public List<DataItem> Items 
    {
        get
        {
            return _items;
        }
    }

    public string Name { get; set; }
    public int Category { get; set; }
    public bool IsEnabled { get; set; }
}

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        List<DataItem> allData = new List<DataItem>();

        DataItem i1 = new DataItem() { Name = "Test1", Category = 1, IsEnabled = false };
        DataItem i2 = new DataItem() { Name = "Test2", Category = 2, IsEnabled = false };
        DataItem i3 = new DataItem() { Name = "Test3", Category = 3, IsEnabled = true };

        DataItem t1 = new DataItem() { Name = "Template 1", Category = 1, IsEnabled = true  };
        DataItem t2 = new DataItem() { Name = "Template 2", Category = 1, IsEnabled = false };

        i1.Items.Add(t1);
        i1.Items.Add(t2);

        allData.Add(i1);
        allData.Add(i2);
        allData.Add(i3);
        tree_3.ItemsSource = allData;
    }

Resolví el problema con el siguiente método.

  1. crear un recurso de menú contextual

    <ContextMenu x:Uid="ContextMenu_1" x:Key="TreeViewItemContextMenu"
             ItemsSource="{Binding}">
        <MenuItem x:Uid="MenuItem_1" 
              Header="Rename" 
              IsEnabled="{Binding Path=., Converter={StaticResource renameMenuConverter}}"
              Click="RenameMenu_OnClick"
              />
    </ContextMenu>
    
  2. cree un estilo para el elemento de vista de árbol y use el recurso del menú contextual anterior

    <Style TargetType="{x:Type TreeViewItem}" x:Uid="Style_1">
    <Setter x:Uid="Setter_32" Property="ContextMenu" Value="{StaticResource           TreeViewItemContextMenu}">
    </Setter>
    ...
    </Style>
    
  3. implementar un convertidor. De acuerdo con la extensión de marcado anterior, el parámetro pasado en convertir es el elemento seleccionado actual, por lo que puedo obtener la propiedad y realizar la verificación.

Gracias por toda tu ayuda.

preguntado el 22 de mayo de 12 a las 12:05

1 Respuestas

He usado esto en WinForm TreeView con resultados exitosos.

Al declarar los elementos de datos, también incluya una propiedad de etiqueta en ellos.

DataItem i1 = new DataItem() { Name = "Test1", 
                  Category = 1, IsEnabled = false, Tag = "Test1" };

En EventListener para TreeView, transmita el objeto del remitente u obtenga el SelectedItem de TreeView.

//It is only Algorithm:
if treeview1.selecedItem.Tag = "Test1" then
    //code for execution
end if

Del mismo modo para el objeto emisor,

//It is only Algorithm:
variable treeNode = cast ( sender to TreeView ).SelectedItem
if treeNode.Tag = "Test1" then
    //code for execution
end if

En cuanto al "código de ejecución", puede habilitar o deshabilitar los MenuItems.

NOTA: No ha declarado el atributo x:Name para los MenuItems en la etiqueta ContextMenu. Hágalo para acceder a los elementos del menú.

IsEnabled es la propiedad directa para habilitar o deshabilitar los elementos interactuables en WPF

Acabo de dar el algoritmo porque soy más un tipo de VB que de C#. Así que no quiero estropearme con los códigos.

Que tengas un gran día :)

contestado el 22 de mayo de 12 a las 13:05

También puede agregar identificadores únicos en la propiedad Etiqueta. Puede preguntar "¿Puedo usar el nombre del elemento de datos para acceder a ellos?" Pero para hacer eso, los declara Globalmente como Amigo o lo usa en el Código de Diseñador. De lo contrario, no puede manejar ese objeto. También puede agregar un detector de eventos explícito para que los elementos de datos hagan el trabajo. ¡Como siempre, un programador tiene tantas tácticas como ramas en un árbol! - La sandalia negra

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.