[英]Using WPF, how can I programmatically disable buttons that were created in XAML for a Listview control?
我創建了一個 WPF 列表視圖,並填充了 ProductCategory 的實例。
public class ProductCategory
{
public int Id { get; set; }
public string CategoryName { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime LastUpdated { get; set; }
}
接下來我創建列表,填充它並將其分配給 Listview 控件。
私有列表 myProductList = new List();
// 添加一些項目到 myProductList
// 將產品列表分配給 ListView 的 ItemsSource 屬性
myListView.ItemsSource = myProductList;
在 XAML 代碼中,每行都添加了一個標有“編輯”的按鈕。 每行代表 ProductCategory 的一個實例:
<ListView x:Name="myListView" Height="352" HorizontalAlignment="Left" Margin="20,90,0,0" VerticalAlignment="Top" Width="1008">
<ListView.View>
<GridView>
<GridViewColumn Header="Category Name" DisplayMemberBinding="{Binding CategoryName}" Width="200"/>
<GridViewColumn Header="Created Date" DisplayMemberBinding="{Binding CreatedDate}" Width="200"/>
<GridViewColumn Header="Last Updated" DisplayMemberBinding="{Binding LastUpdated}" Width="200"/>
<GridViewColumn Header="Edit" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Edit" Click="EditCategory" CommandParameter="{Binding}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
當用戶單擊該按鈕時,將出現一個對話框,用戶可以編輯 ProductCategory 實例的數據。 當用戶關閉對話框時,用戶將返回到列表視圖。
此時我想禁用 Listview 中的所有按鈕。 我怎樣才能以編程方式實現這個目標?
這些按鈕在 myListView.ItemsSource 中不可訪問。
我創建了一個列表來存儲結果。 您可以看到我從列表中隨機選擇了幾個按鈕並將其禁用。 Button_Click 來自我添加的按鈕,因此我可以從某個地方開始。 在 IntializeComponent() 之后從構造函數中執行代碼應該會為您提供所有按鈕的列表
List<Button> buttons =
new List<Button>();
private void Button_Click(object sender, RoutedEventArgs e)
{
myListView.Items
.Cast<dynamic>()
.ToList()
.ForEach(item => {
var listviewitem =
(ListViewItem)
(myListView
.ItemContainerGenerator
.ContainerFromItem(item));
Button editbutton =
FindVisualChild<Button>
(listviewitem);
buttons
.Add(editbutton);
});
buttons[1]
.IsEnabled = false;
buttons[3]
.IsEnabled = false;
}
private childItem FindVisualChild<childItem>(DependencyObject obj)
where childItem : DependencyObject
{
for (int i = 0;
i < VisualTreeHelper
.GetChildrenCount(obj);
i++)
{
DependencyObject child =
VisualTreeHelper
.GetChild(obj, i);
if (child != null
&& child is childItem)
{
return
(childItem)child;
}
else
{
childItem childOfChild =
FindVisualChild<childItem>
(child);
if (childOfChild != null)
return
childOfChild;
}
}
return null;
}
從建議的解決方案中,這里是解決我的問題的代碼:
private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is childItem)
{
return (childItem)child;
}
else
{
childItem childOfChild = FindVisualChild<childItem>(child);
if (childOfChild != null)
{
return childOfChild;
}
}
}
return null;
}
private void disableEditButtonsInListView()
{
myListView.Items.Cast<dynamic>().ToList().ForEach(item =>
{
var myListViewItem = (ListViewItem)(myListView.ItemContainerGenerator.ContainerFromItem(item));
Button editButton = FindVisualChild<Button>(myListViewItem);
if (editButton != null)
{
editButton.IsEnabled = false;
}
});
}
使用 MVVM 很容易做到這一點。
我展示了一個簡單的例子——它在某種程度上打破了 MVVM,但會讓你了解它應該如何工作。
using Simplified;
using System;
using System.Collections.ObjectModel;
using System.Windows;
namespace Core2022.SO.user2949159
{
public class ProductsViewModel : BaseInpc
{
public ObservableCollection<ProductCategory> Products { get; } = new()
{
new ProductCategory() {Id = 1, CategoryName = "Electronics", CreatedDate = DateTime.Now.AddDays(-15).Date, LastUpdated= DateTime.Now.AddDays(-5).Date},
new ProductCategory() {Id = 2, CategoryName = "Сlothes", CreatedDate = DateTime.Now.AddDays(-7).Date, LastUpdated= DateTime.Now.AddDays(-1).Date}
};
private RelayCommand? _editCommand;
private bool _editingOff;
public RelayCommand EditCommand => _editCommand ??= new RelayCommand<ProductCategory>(EditExecute, EditCanExecute);
public bool EditingOff
{
get => _editingOff;
set
{
if (Set(ref _editingOff, value))
EditCommand.RaiseCanExecuteChanged();
}
}
private bool EditCanExecute(ProductCategory product) => !EditingOff;
private void EditExecute(ProductCategory product)
{
// Some Code for edit product
MessageBox.Show($"{product.Id}: {product.CategoryName}");
}
}
<Window x:Class="Core2022.SO.user2949159.ProductsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Core2022.SO.user2949159"
mc:Ignorable="d"
Title="ProductsWindow" Height="450" Width="800"
DataContext="{DynamicResource vm}">
<Window.Resources>
<local:ProductsViewModel x:Key="vm"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<CheckBox Content="Editing Off" IsChecked="{Binding EditingOff}" Margin="5"/>
<ListView Grid.Row="1" ItemsSource="{Binding Products}" HorizontalAlignment="Left" Margin="20">
<ListView.View>
<GridView>
<GridViewColumn Header="Category Name" DisplayMemberBinding="{Binding CategoryName}" Width="200"/>
<GridViewColumn Header="Created Date" DisplayMemberBinding="{Binding CreatedDate}" Width="200"/>
<GridViewColumn Header="Last Updated" DisplayMemberBinding="{Binding LastUpdated}" Width="200"/>
<GridViewColumn Header="Edit" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Edit"
CommandParameter="{Binding}"
Command="{Binding EditCommand, Mode=OneWay, Source={StaticResource vm}}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.