C# 在父列表视图中仅显示选定项的用户控件按钮可见性

C# 在父列表视图中仅显示选定项的用户控件按钮可见性,c#,wpf,mvvm-light,C#,Wpf,Mvvm Light,我在listview的datatemplate中有一个usercontrol deletecontrol。在当前代码中,当我为所选项目单击usercontrol上的按钮时,usercontrol的命令将在列表中的所有项目中执行。 我为所有按钮的可见性属性实现了INotifyPropertychanged。 MainVM是MainWindow的datacontext,DeleteVM是UserControl的viewmodel。我需要有关按钮可见性的帮助,以确保在单击btnX执行DeleteCmd

我在listview的datatemplate中有一个usercontrol deletecontrol。在当前代码中,当我为所选项目单击usercontrol上的按钮时,usercontrol的命令将在列表中的所有项目中执行。 我为所有按钮的可见性属性实现了INotifyPropertychanged。 MainVM是MainWindow的datacontext,DeleteVM是UserControl的viewmodel。我需要有关按钮可见性的帮助,以确保在单击btnX执行DeleteCmd时,btnYes和lblConfirm仅显示在listview的选定项中

DeleteVM.cs

  public RelayCommand DeleteCmd { get; private set; }
    public DeleteVM()
    {           
        DeleteCmd = new RelayCommand(() => ShowDelete(), () => true);
    }
     private void ShowDelete()   
     {System.Windows.Application.Current.Dispatcher.Invoke

       (DispatcherPriority.Normal,(Action)delegate()
         {
           BtnXVisibility = Visibility.Hidden;
           BtnYesVisibility = System.Windows.Visibility.Visible;

           LblConfirmVisibility = System.Windows.Visibility.Visible;
           Background = Brushes.White;
          });
    }
MainWindow.xaml

 <ListView Name="listView" ItemsSource="{Binding Source={StaticResource collection}}" SelectedItem="{Binding Item, Mode=TwoWay}">
     <ListView.ItemTemplate>
         <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Image Width="12" Height="12"  Source="{Binding ImageString}"/>                      
                    <TextBlock Grid.Column="1">
                        <TextBlock.Text>
                            <MultiBinding StringFormat=" {0} - {1} - {2}">
                                <Binding Path="Timestamp" />
                                <Binding Path="User" />
                                <Binding Path="Description" />
                            </MultiBinding>
                        </TextBlock.Text>
                    </TextBlock>
                    <view:Deletecontrol Grid.Column="2"   
                      HorizontalAlignment="Right"/>
                </Grid>
            </DataTemplate>
      </ListView.ItemTemplate>
      </ListView>
Deletecontrol.Xaml

   <Grid>
        <Button Grid.Column="2" Name="btnX" Foreground="Red"  
            Visibility="{Binding BtnXVisibility, 
              Mode=TwoWay, Path=SelectedItem, 
            RelativeSource={RelativeSource AncestorType={x:Type 
            ListView}}}"  Command="{Binding DeleteCmd}"
            CommandParameter="{Binding Path=SelectedItem, RelativeSource=
            {RelativeSource AncestorType={x:Type ListView}}}" > 
       </Button.Background> X</Button>         
       <Label Grid.Column="0" Name="lblConfirm" Visibility="{Binding 
          LblConfirmVisibility, Mode=OneWay}">Are you sure? </Label>
      <Button Grid.Column="1" Margin="0,0,3,0" Width="30"       
         HorizontalAlignment="Left" Name="btnYes" Visibility="{Binding 
         BtnYesVisibility, Mode=TwoWay}" Command="{Binding OnDeleteCmd}">
      </Button.Background> Yes</Button>
   </Grid>

我使用VisualTreeHelper获取所选listview项的按钮。 下面是xaml和viewmodel代码

DeleteControl.xaml

    <Button Grid.Column="2" Name="btnX" Foreground="Red" FontWeight="Bold" Visibility="{Binding BtnXVisibility,Converter={StaticResource boolToVisibilityConverter}}"  
        Command="{Binding ShowDeleteCmd}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, 
        AncestorType=ListViewItem}}" ToolTip="Delete this item">
删除虚拟机

    public RelayCommand<ListViewItem> DeleteCmd { get; private set; }
     /// <summary>
    /// View Model for Delete Window.
    /// </summary>
    public DeleteVM()
    {
       DeleteCmd = new RelayCommand<ListViewItem>(ShowDelete);
    }
    /// <summary>
    /// Method to Show Delete options.
    /// </summary>
    private void ShowDelete(ListViewItem lv)
    {
        Button btnX = FindChild<Button>(lv,"btnX");
        Button btnYes = FindChild<Button>(lv, "btnYes");
        Button btnNo = FindChild<Button>(lv, "btnNo");
        Label lblConfirm = FindChild<Label>(lv, "lblConfirm" );           

        System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal,
         (Action)delegate()
         {
             btnX.Visibility = Visibility.Hidden;
             btnYes.Visibility = Visibility.Visible;
             btnNo.Visibility = Visibility.Visible;
             lblConfirm.Visibility = Visibility.Visible;
             //BtnXVisibility = Visibility.Hidden;
             //BtnYesVisibility = System.Windows.Visibility.Visible;
             //btnNoVisibility = System.Windows.Visibility.Visible;
             //LblConfirmVisibility = System.Windows.Visibility.Visible;
             Background = Brushes.White;
         });
    }
    public static T FindChild<T>(DependencyObject parent, string childName)
       where T : DependencyObject
    {
        // Confirm parent and childName are valid. 
        if (parent == null) return null;

        T foundChild = null;

        int childrenCount = System.Windows.Media.VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = System.Windows.Media.VisualTreeHelper.GetChild(parent, i);
            // If the child is not of the request child type child
            T childType = child as T;
            if (childType == null)
            {
                // recursively drill down the tree
                foundChild = FindChild<T>(child, childName);

                // If the child is found, break so we do not overwrite the found child. 
                if (foundChild != null) break;
            }
            else if (!string.IsNullOrEmpty(childName))
            {
                var frameworkElement = child as FrameworkElement;
                // If the child's name is set for search
                if (frameworkElement != null && frameworkElement.Name == childName)
                {
                    // if the child's name is of the request name
                    foundChild = (T)child;
                    break;
                }
            }
            else
            {
                // child element found.
                foundChild = (T)child;
                break;
            }
        }

        return foundChild;
    }
这个链接帮助了我。