是否可以将控件的TabIndex绑定到GridView中列的顺序?比如,我们将一个GridView的AllowColumnReorder设置为true,当我们将第二列拖到最后时,选项卡导航顺序将保持按列顺序排列:1 - > 3 - > 2,而不是1-> 2 - > 3通常。我想要做的是根据第二张图像上的实际列布局选项卡导航。
我的kxaml代码:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ListView ItemsSource="2"
Grid.Row="1">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn Header="One">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="1"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Two">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="2"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Three">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="3"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Page>
答案 0 :(得分:2)
这是一个使用datagrid而不是
的示例<DataGrid ItemsSource="2" Grid.Row="1">
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header="One">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="1" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Two">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="2" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Three">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="3" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
修改强>
这是一个有效的listview解决方案,但我认为它不是最好的......
public class CustomGridViewColumn : GridViewColumn
{
public static readonly DependencyProperty ColumnIndexProperty =
DependencyProperty.Register("ColumnIndex", typeof(int), typeof(CustomGridViewColumn),
new FrameworkPropertyMetadata());
public int ColumnIndex {
get { return (int)GetValue(ColumnIndexProperty); }
set { SetValue(ColumnIndexProperty, value); }
}
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
gridView.Columns.CollectionChanged+= new NotifyCollectionChangedEventHandler(gridView_Columns_CollectionChanged);
}
void gridView_Columns_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var index = 0;
foreach(CustomGridViewColumn col in gridView.Columns){
col.ColumnIndex=index++;
}
}
}
<ListView KeyboardNavigation.TabNavigation="Cycle">
<ListView.View>
<GridView x:Name="gridView" AllowsColumnReorder="True">
<local:CustomGridViewColumn Header="One" x:Name="col1">
<local:CustomGridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="1" TabIndex="{Binding Path=ColumnIndex, Mode=OneWay, ElementName=col1}"/>
</DataTemplate>
</local:CustomGridViewColumn.CellTemplate>
</local:CustomGridViewColumn>
<local:CustomGridViewColumn Header="Two" x:Name="col2">
<local:CustomGridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="2" TabIndex="{Binding Path=ColumnIndex, Mode=OneWay, ElementName=col2}"/>
</DataTemplate>
</local:CustomGridViewColumn.CellTemplate>
</local:CustomGridViewColumn>
<local:CustomGridViewColumn Header="Three" x:Name="col3">
<local:CustomGridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="100" Text="3" TabIndex="{Binding Path=ColumnIndex, Mode=OneWay, ElementName=col3}"/>
</DataTemplate>
</local:CustomGridViewColumn.CellTemplate>
</local:CustomGridViewColumn>
</GridView>
</ListView.View>
<ListViewItem>1</ListViewItem>
<ListViewItem>2</ListViewItem>
<ListViewItem>3</ListViewItem>
</ListView>
希望这会有所帮助
答案 1 :(得分:1)
如果您改为使用DataGrid:列具有DisplayIndex属性,该属性保存当前索引,即使它们被重新排序也是如此。
答案 2 :(得分:1)
这是一个重要的开始。剩下要做的唯一事情就是遍历GridView的ListView的Items并在行(//! iterate ListView rows
)中设置tab index foreach元素。一些逻辑可能搞砸了,因为代码匆忙..
XAML
<GridView
AllowsColumnReorder="True"
Controls:GridViewExtensions.DoTabIndexing="True">...
C#
/// <summary>Provides members helpful to <see cref="GridView"/>.</summary>
public static class GridViewExtensions
{
#region DoTabIndexing
[Category("Common")]
[AttachedPropertyBrowsableForType(typeof(GridView))]
public static bool GetDoTabIndexing(GridView gridView)
{
return (bool)gridView.GetValue(DoTabIndexingProperty);
}
public static void SetDoTabIndexing(GridView gridView, bool value)
{
gridView.SetValue(DoTabIndexingProperty, value);
}
public static readonly DependencyProperty DoTabIndexingProperty =
DependencyProperty.RegisterAttached(
"DoTabIndexing",
typeof(bool), // type
typeof(GridViewExtensions), // container/holder/control
new PropertyMetadata(default(bool), OnDoTabIndexingChanged)
);
private static void OnDoTabIndexingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var gridView = (GridView)d;
if (gridView.AllowsColumnReorder == false) { return; }
var newValue = (bool)e.NewValue;
_indexWatch = new ColumnIndexWatch(gridView);
}
static ColumnIndexWatch _indexWatch;
#endregion DoTabIndexing
/// <summary>Watches for changes in a <see cref="GridView"/>'s columns.</summary>
class ColumnIndexWatch
{
readonly GridView _gridView;
public ColumnIndexWatch(GridView gridView)
{
_gridView = gridView;
gridView.Columns.CollectionChanged += OnItemsPopulated;
}
void OnItemsPopulated(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action != NotifyCollectionChangedAction.Add)
{
_gridView.Columns.CollectionChanged -= OnItemsPopulated;
_gridView.Columns.CollectionChanged += OnItemMoved;
trax = new ColumnIndexCollection(_gridView.Columns);
OnItemMoved(sender, e);
}
}
ColumnIndexCollection trax;
void OnItemMoved(object sender, NotifyCollectionChangedEventArgs e)
{
var movedColumn = e.NewItems[0] as GridViewColumn;
if (movedColumn == null) { return; }
trax.ApplyNewIndex(movedColumn, e.NewStartingIndex);
}
/// <summary>Represents a collection of <see cref="ColumnIndex"/></summary>
class ColumnIndexCollection : Collection<ColumnIndex>
{
public ColumnIndexCollection(IEnumerable<GridViewColumn> columns)
: base(Create(columns)) { }
static IList<ColumnIndex> Create(IEnumerable<GridViewColumn> columns)
{
return columns.Select((t, i) => new ColumnIndex { GridViewColumn = t, Index = i }).ToList();
}
public void ApplyNewIndex(GridViewColumn column, int newIndex)
{
var movedByUser = Items.First(col => col.GridViewColumn == column);
var placeTaken = Items.First(col => col.Index == newIndex);
placeTaken.Index = movedByUser.Index;
movedByUser.Index = newIndex;
movedByUser.Update();
placeTaken.Update();
//! iterate ListView rows
}
}
/// <summary>Represents a <see cref="System.Windows.Controls.GridViewColumn"/> and its index.</summary>
class ColumnIndex
{
public GridViewColumn GridViewColumn { get; set; }
public int Index { get; set; }
public void Update()
{
KeyboardNavigation.SetTabIndex(GridViewColumn, Index);
}
public override string ToString()
{
return string.Format("{0} : {1}", Index, GridViewColumn);
}
}
}
}