我有一个自定义Datagrid,在datagrid中我改变了选择元素的方式。
我在选择中添加了一些功能,例如:
它是一个DataGrid扩展,所以我只在C#编码。
为此,我在PreviewMouseDown上添加了事件句柄,为datagridrow添加了MouseUp。
private enum ButtonClicked {Left, Middle, Right};
private ButtonClicked m_oMouseButtonClicked;
private void PreviewMouseDownHandler(object sender, MouseButtonEventArgs e)
{
DataGridRow row = sender as DataGridRow;
if (e.LeftButton == MouseButtonState.Pressed)
{
row.IsSelected = !row.IsSelected;
m_oMouseButtonClicked = ButtonClicked.Left;
}
else if (e.RightButton == MouseButtonState.Pressed)
{
//row.IsSelected = !row.IsSelected;
m_oMouseButtonClicked = ButtonClicked.Right;
}
row.CaptureMouse();
row.MouseMove += row_MouseMove;
e.Handled = true;
}
void row_MouseMove(object sender, MouseEventArgs e)
{
Point oPosFromThis = e.GetPosition(this);
if (oPosFromThis.Y > this.ActualHeight)
{
}
else if (oPosFromThis.Y < 0)
{
}
}
void Row_MouseUp(object sender, MouseButtonEventArgs e)
{
int nStart;
int nEnd;
DataGridRow row = sender as DataGridRow;
row.ReleaseMouseCapture();
row.MouseMove -= row_MouseMove;
int nStartRowIndex = ItemContainerGenerator.IndexFromContainer(row);
Point oPosFromRow = e.MouseDevice.GetPosition(row);
int nEndRowIndex = nStartRowIndex + (int)Math.Floor(oPosFromRow.Y / row.ActualHeight);
if (nStartRowIndex < nEndRowIndex)
{
nStart = Math.Max(nStartRowIndex, 0);
nEnd = Math.Min(nEndRowIndex, Items.Count - 1);
}
else
{
nStart = Math.Max(nEndRowIndex, 0);
nEnd = Math.Min(nStartRowIndex, Items.Count - 1);
}
for (; nStart <= nEnd; ++nStart)
{
DataGridRow oTmp = ((DataGridRow)ItemContainerGenerator.ContainerFromIndex(nStart));
if (m_oMouseButtonClicked == ButtonClicked.Left)
{
oTmp.IsSelected = row.IsSelected;
}
else if (m_oMouseButtonClicked == ButtonClicked.Right)
{
oTmp.IsSelected = !oTmp.IsSelected;
}
}
e.Handled = true;
}
我将鼠标捕获到我点击的行中,即使我走到数据网格之外也能捕获mouseUp。
但是凭我的代码,我失去了一个我想拥有的功能。当我进行多项选择时,自动滚动,我在数据网格下面或上面。我知道我将不得不添加MouseMove Handler来实现它,但是现在我卡住了因为我不知道该怎么做。
答案 0 :(得分:0)
我终于通过尝试错误尝试找到了解决方案。我添加了方法来获取scrollviewer元素,然后我启动一个Timer来单独执行滚动。
public claa AAA
{
private enum ButtonClicked {Left, Middle, Right};
private ButtonClicked m_oMouseButtonClicked;
private DispatcherTimer m_oTimer;
private double m_nScrollOffset;
private ScrollViewer m_oScrollBar;
public IcuAlertGrid()
{
this.Initialized += IcuAlertGrid_Initialized;
this.Loaded += IcuAlertGrid_Loaded;
m_oTimer = new DispatcherTimer();
m_oTimer.Tick += m_oTimer_Tick;
m_oTimer.Interval = new TimeSpan(2500000);
}
void IcuAlertGrid_Initialized(object sender, EventArgs e)
{
setStyle0(true);
//throw new NotImplementedException();
}
void IcuAlertGrid_Loaded(object sender, RoutedEventArgs e)
{
m_oScrollBar = GetScrollViewer(this);
}
void m_oTimer_Tick(object sender, EventArgs e)
{
if (m_oScrollBar != null)
{
m_oScrollBar.ScrollToVerticalOffset(m_oScrollBar.VerticalOffset + m_nScrollOffset);
}
}
private void PreviewMouseDownHandler(object sender, MouseButtonEventArgs e)
{
DataGridRow row = sender as DataGridRow;
if (e.LeftButton == MouseButtonState.Pressed)
{
row.IsSelected = !row.IsSelected;
m_oMouseButtonClicked = ButtonClicked.Left;
}
else if (e.RightButton == MouseButtonState.Pressed)
{
//row.IsSelected = !row.IsSelected;
m_oMouseButtonClicked = ButtonClicked.Right;
}
row.CaptureMouse();
row.MouseMove += row_MouseMove;
e.Handled = true;
}
private void row_MouseMove(object sender, MouseEventArgs e)
{
DataGridRow oRow = sender as DataGridRow;
Point oPosFromThis = e.GetPosition(this);
if (oPosFromThis.Y < 0)
{
m_nScrollOffset = -1.0;
m_oTimer.Start();
}
else if (this.ActualHeight < oPosFromThis.Y)
{
m_nScrollOffset = 1.0;
m_oTimer.Start();
}
else
{
m_oTimer.Stop();
}
}
private void Row_MouseUp(object sender, MouseButtonEventArgs e)
{
int nStart;
int nEnd;
m_oTimer.Stop();
DataGridRow row = sender as DataGridRow;
row.ReleaseMouseCapture();
row.MouseMove -= row_MouseMove;
int nStartRowIndex = ItemContainerGenerator.IndexFromContainer(row);
Point oPosFromRow = e.MouseDevice.GetPosition(row);
int nEndRowIndex = nStartRowIndex + (int)Math.Floor(oPosFromRow.Y / row.ActualHeight);
if (nStartRowIndex < nEndRowIndex)
{
nStart = Math.Max(nStartRowIndex, 0);
nEnd = Math.Min(nEndRowIndex, Items.Count - 1);
}
else
{
nStart = Math.Max(nEndRowIndex, 0);
nEnd = Math.Min(nStartRowIndex, Items.Count - 1);
}
for (; nStart <= nEnd; ++nStart)
{
DataGridRow oTmp = ((DataGridRow)ItemContainerGenerator.ContainerFromIndex(nStart));
if (m_oMouseButtonClicked == ButtonClicked.Left)
{
oTmp.IsSelected = row.IsSelected;
}
else if (m_oMouseButtonClicked == ButtonClicked.Right)
{
oTmp.IsSelected = !oTmp.IsSelected;
}
}
e.Handled = true;
}
private static ScrollViewer GetScrollViewer(DependencyObject p_oParent)
{
ScrollViewer child = default(ScrollViewer);
int numVisuals = VisualTreeHelper.GetChildrenCount(p_oParent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(p_oParent, i);
child = v as ScrollViewer;
if (child == null)
{
child = GetScrollViewer(v);
}
if (child != null)
{
break;
}
}
return child;
}
}