Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WPF中的DataGridRow上显示控件_C#_Wpf_Xaml - Fatal编程技术网

C# 在WPF中的DataGridRow上显示控件

C# 在WPF中的DataGridRow上显示控件,c#,wpf,xaml,C#,Wpf,Xaml,只有当用户在静态数据网格中悬停其行时,才可以非常方便地显示特定项的数据。我尝试的是:将MouseEnter和MouseLeave事件链接到将保存当前悬停项索引的方法,创建一个转换器,该转换器将比较项索引是否为悬停项索引(如果是,则显示,否则隐藏),最后,在静态DataGrid ItemSource上调用static INPC,但似乎我仍然缺少一些东西。(我正在以MVVM模式编码,但由于这是严格面向视图的,如果解决方案涉及代码隐藏,我没有问题) tl;博士:我想做到这一点: 以下是我为方便测试所

只有当用户在静态数据网格中悬停其行时,才可以非常方便地显示特定项的数据。我尝试的是:将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 static
INPC
和static
MyList
,因为这是我找到的使转换器能够访问列表的唯一方法@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>