C# 在WPF中的DataGridRow上显示控件
只有当用户在静态数据网格中悬停其行时,才可以非常方便地显示特定项的数据。我尝试的是:将MouseEnter和MouseLeave事件链接到将保存当前悬停项索引的方法,创建一个转换器,该转换器将比较项索引是否为悬停项索引(如果是,则显示,否则隐藏),最后,在静态DataGrid ItemSource上调用static INPC,但似乎我仍然缺少一些东西。(我正在以MVVM模式编码,但由于这是严格面向视图的,如果解决方案涉及代码隐藏,我没有问题) tl;博士:我想做到这一点: 以下是我为方便测试所做工作的完整代码:C# 在WPF中的DataGridRow上显示控件,c#,wpf,xaml,C#,Wpf,Xaml,只有当用户在静态数据网格中悬停其行时,才可以非常方便地显示特定项的数据。我尝试的是:将MouseEnter和MouseLeave事件链接到将保存当前悬停项索引的方法,创建一个转换器,该转换器将比较项索引是否为悬停项索引(如果是,则显示,否则隐藏),最后,在静态DataGrid ItemSource上调用static INPC,但似乎我仍然缺少一些东西。(我正在以MVVM模式编码,但由于这是严格面向视图的,如果解决方案涉及代码隐藏,我没有问题) tl;博士:我想做到这一点: 以下是我为方便测试所
- 看法
- 代码隐藏:
公共部分类主窗口:窗口
{
//静态INPC(可能是问题所在?)
公共静态事件属性ChangedEventHandler StaticPropertyChanged;
私有静态void NotifyStaticPropertyChanged([CallerMemberName]字符串名称=null)
{
StaticPropertyChanged?.Invoke(空,新PropertyChangedEventArgs(名称));
}
//悬停行索引
公共静态int HoveredRowID{get;set;}=-1;
//DataGrid的ItemSource
私有静态ObservaleCollection_myList=新ObservaleCollection(){1,2,3,4,5};
公共静态可观测集合MyList
{
获取{return\u myList;}
设置{u myList=value;
NotifyStaticPropertyChanged();
}
}
//建造师
公共主窗口()
{
DataContext=this;
初始化组件();
}
//方法,该方法检索悬停行的id并调用INPC。检索部分正在工作,但视图未更新
私有void DataGridRow\u MouseEnter(对象发送方,MouseEventArgs e)
{
DataGridRow=(DataGridRow)发送方;
if(row.Item为int)
{
int item=(int)row.item;
HoveredRowID=MyList.IndexOf(项目);
NotifyStaticPropertyChanged(“MyList”);
}
}
//方法重新设置悬停行的种子,并调用INPC来隐藏以前显示的内容
私有void DataGridRow_MouseLeave(对象发送方,MouseEventArgs e)
{
HoveredRowID=-1;
NotifyStaticPropertyChanged(“MyList”);
}
}
//转换器
公共类HoveredRowToVisibilityConverter:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
if(值为int)
{
int项=(int)值;
//检查此项是否为悬停项
if(MainWindow.MyList.IndexOf(项)==MainWindow.HoveredRowID)
返回可见性。可见;
其他的
返回可见性。隐藏;
}
其他的
返回可见性。隐藏;
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
我想你可以绑定按钮。可见性到在DataGridRow
上是鼠标悬停的。我不认为有任何必要去幻想(或者在代码中隐藏任何东西)。@Mitch的说明是正确的,绑定了按钮。对DataGridRow
的可见性是解决方案。然而,能够做到这一点的一个重要细节是使用DataTrigger
进行绑定,并将默认的visibility
设置为Hidden
/Collapsed
。这里我使用了DataTemplate.Triggers
,但也可以在按钮.Triggers中完成
<DataTemplate>
<Button x:Name="HiddenDeleteButton" Text="Delete" Visibility="Hidden" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="True">
<Setter Property="Visibility" TargetName="HiddenDeleteButton" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
BindingList
适用于Winforms,请改用ObservableCollection
。@aepot rou是对的,已编辑!为什么是静态INPC?鼠标悬停时会出现一些额外的东西。你考虑过工具提示吗?另一种常用的模式是绑定selecteditem,因为面板的datacontext位于datagrid的一侧或下方。您可以在鼠标上方选择一行。@aepot staticINPC
和staticMyList
,因为这是我找到的使转换器能够访问列表的唯一方法@Andy我还想显示一些控件,比如删除按钮,但它不能很好地显示在工具提示中。我想要实现的一个很好的例子是,删除按钮在您的评论中是如何出现和消失的
public partial class MainWindow : Window
{
// Static INPC (maybe is the problem?)
public static event PropertyChangedEventHandler StaticPropertyChanged;
private static void NotifyStaticPropertyChanged([CallerMemberName] string name = null)
{
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(name));
}
// Hovered Row Index
public static int HoveredRowID { get; set; } = -1;
// DataGrid's ItemSource
private static ObservableCollection<int> _myList = new ObservableCollection<int>() { 1, 2, 3, 4, 5 };
public static ObservableCollection<int> MyList
{
get { return _myList; }
set { _myList = value;
NotifyStaticPropertyChanged();
}
}
// Constructor
public MainWindow()
{
DataContext = this;
InitializeComponent();
}
// Method that retrieves the id of the Hovered Row and calls INPC. The retrieving part is working, but the View isn't updating
private void DataGridRow_MouseEnter(object sender, MouseEventArgs e)
{
DataGridRow row = (DataGridRow)sender;
if (row.Item is int)
{
int item = (int)row.Item;
HoveredRowID = MyList.IndexOf(item);
NotifyStaticPropertyChanged("MyList");
}
}
// Method that resests the Hovered Row and call INPC to hide the previously shown stuff
private void DataGridRow_MouseLeave(object sender, MouseEventArgs e)
{
HoveredRowID = -1;
NotifyStaticPropertyChanged("MyList");
}
}
// The converter
public class HoveredRowToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int)
{
int item = (int)value;
// Check if this item is the hovered item
if (MainWindow.MyList.IndexOf(item) == MainWindow.HoveredRowID)
return Visibility.Visible;
else
return Visibility.Hidden;
}
else
return Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<DataTemplate>
<Button x:Name="HiddenDeleteButton" Text="Delete" Visibility="Hidden" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="True">
<Setter Property="Visibility" TargetName="HiddenDeleteButton" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>