用户控制按钮的可见性仅适用于父列表视图中的选定项目
本文关键字:视图 列表 项目 适用于 按钮 控制 可见性 用户 | 更新日期: 2023-09-27 18:20:34
我在列表视图的数据模板中有一个用户控件"deletecontrol"。使用我的当前代码,当我单击用户控件上所选项目的按钮时,用户控件的命令将在列表中的所有项目中执行。我为所有按钮的可见性属性实现了INotifyPropertychanged。MainVM是MainWindow的数据上下文,DeleteVM是UserControl的视图模型。我需要有关按钮可见性的帮助,以确保当我单击btnX执行DeleteCmd时,btnYes和lblConfirm仅显示在列表视图的选定项目中。
删除VM.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;
});
}
主窗口.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>
删除控制。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>
我使用可视化树助手来获取所选列表视图项的按钮。这是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">
删除VM
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;
}