첫 번째 열이 텍스트 열이고 두 번째 열이 CheckBox 열인 DataGrid가 있습니다. 확인란을 클릭하면 원하는 것입니다. 확인해야합니다.
그러나 선택하려면 두 번의 클릭이 필요합니다. 첫 번째 클릭의 경우 셀이 선택되고 두 번째 클릭의 경우 확인란이 선택됩니다. 한 번의 클릭으로 확인란을 선택 / 선택 취소하는 방법.
WPF 4.0을 사용하고 있습니다. DataGrid의 열은 자동 생성됩니다.
답변
한 번의 클릭으로 DataGrid 확인란의 경우 일반 확인란 컨트롤을 내부에 DataGridTemplateColumn
넣고 설정할 수 UpdateSourceTrigger=PropertyChanged
있습니다.
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=IsSelected, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
답변
나는 다음 스타일로 이것을 해결했다.
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
물론 특정 열에 맞게이를 더 조정할 수 있습니다 …
답변
첫째, 나는 이것이 꽤 오래된 질문이라는 것을 알고 있지만 여전히 시도하고 답할 것이라고 생각했습니다.
나는 며칠 전에 같은 문제가 있었고 놀랍게도 짧은 해결책을 찾았습니다 ( 이 블로그 참조 ). 기본적으로 DataGridCheckBoxColumn
XAML 의 정의를 다음으로 바꾸면됩니다.
<DataGridTemplateColumn Header="MyCheckBoxColumnHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding Path=MyViewModelProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
이 솔루션의 장점은 명백합니다. XAML 전용입니다. 따라서 추가 UI 로직으로 코드 백에 부담을주지 않도록 효과적으로 억제하고 MVVM 열광의 눈에 상태를 유지하는 데 도움이됩니다.).
답변
확인하려면 콘스탄틴 Salavatov의 응답 으로 작업을 AutoGenerateColumns
받는 이벤트 처리기를 추가, DataGrid
의 AutoGeneratingColumn
다음 코드 :
if (e.Column is DataGridCheckBoxColumn && !e.Column.IsReadOnly)
{
var checkboxFactory = new FrameworkElementFactory(typeof(CheckBox));
checkboxFactory.SetValue(FrameworkElement.HorizontalAlignmentProperty, HorizontalAlignment.Center);
checkboxFactory.SetValue(FrameworkElement.VerticalAlignmentProperty, VerticalAlignment.Center);
checkboxFactory.SetBinding(ToggleButton.IsCheckedProperty, new Binding(e.PropertyName) { UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
e.Column = new DataGridTemplateColumn
{
Header = e.Column.Header,
CellTemplate = new DataTemplate { VisualTree = checkboxFactory },
SortMemberPath = e.Column.SortMemberPath
};
}
이렇게하면 DataGrid
자동 생성 된 모든 확인란 열을 “단일 클릭”으로 편집 할 수 있습니다.
답변
Goblin의 답변에서 참조 된 블로그를 기반으로하지만 .NET 4.0 및 행 선택 모드에서 작동하도록 수정되었습니다.
또한 편집 모드로 들어가서 한 번의 클릭 또는 텍스트 입력시 드롭 다운을 표시하여 DataGridComboBoxColumn 편집 속도를 높입니다.
XAML :
<Style TargetType="{x:Type DataGridCell}">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" />
<EventSetter Event="PreviewTextInput" Handler="DataGridCell_PreviewTextInput" />
</Style>
코드 숨김 :
private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
GridColumnFastEdit(cell, e);
}
private void DataGridCell_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
GridColumnFastEdit(cell, e);
}
private static void GridColumnFastEdit(DataGridCell cell, RoutedEventArgs e)
{
if (cell == null || cell.IsEditing || cell.IsReadOnly)
return;
DataGrid dataGrid = FindVisualParent<DataGrid>(cell);
if (dataGrid == null)
return;
if (!cell.IsFocused)
{
cell.Focus();
}
if (cell.Content is CheckBox)
{
if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow)
{
if (!cell.IsSelected)
cell.IsSelected = true;
}
else
{
DataGridRow row = FindVisualParent<DataGridRow>(cell);
if (row != null && !row.IsSelected)
{
row.IsSelected = true;
}
}
}
else
{
ComboBox cb = cell.Content as ComboBox;
if (cb != null)
{
//DataGrid dataGrid = FindVisualParent<DataGrid>(cell);
dataGrid.BeginEdit(e);
cell.Dispatcher.Invoke(
DispatcherPriority.Background,
new Action(delegate { }));
cb.IsDropDownOpen = true;
}
}
}
private static T FindVisualParent<T>(UIElement element) where T : UIElement
{
UIElement parent = element;
while (parent != null)
{
T correctlyTyped = parent as T;
if (correctlyTyped != null)
{
return correctlyTyped;
}
parent = VisualTreeHelper.GetParent(parent) as UIElement;
}
return null;
}
답변
나는이 제안들과 다른 사이트에서 찾은 많은 다른 것들을 시도했지만 그중 어느 것도 나를 위해 일하지 않았습니다. 결국 다음과 같은 솔루션을 만들었습니다.
내 DataGrid 상속 컨트롤을 만들고이 코드를 추가했습니다.
public class DataGridWithNavigation : Microsoft.Windows.Controls.DataGrid
{
public DataGridWithNavigation()
{
EventManager.RegisterClassHandler(typeof(DataGridCell),
DataGridCell.PreviewMouseLeftButtonDownEvent,
new RoutedEventHandler(this.OnPreviewMouseLeftButtonDown));
}
private void OnPreviewMouseLeftButtonDown(object sender, RoutedEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
{
DependencyObject obj = FindFirstControlInChildren(cell, "CheckBox");
if (obj != null)
{
System.Windows.Controls.CheckBox cb = (System.Windows.Controls.CheckBox)obj;
cb.Focus();
cb.IsChecked = !cb.IsChecked;
}
}
}
public DependencyObject FindFirstControlInChildren(DependencyObject obj, string controlType)
{
if (obj == null)
return null;
// Get a list of all occurrences of a particular type of control (eg "CheckBox")
IEnumerable<DependencyObject> ctrls = FindInVisualTreeDown(obj, controlType);
if (ctrls.Count() == 0)
return null;
return ctrls.First();
}
public IEnumerable<DependencyObject> FindInVisualTreeDown(DependencyObject obj, string type)
{
if (obj != null)
{
if (obj.GetType().ToString().EndsWith(type))
{
yield return obj;
}
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
foreach (var child in FindInVisualTreeDown(VisualTreeHelper.GetChild(obj, i), type))
{
if (child != null)
{
yield return child;
}
}
}
}
yield break;
}
}
이 모든 것이 무엇을합니까?
데이터 그리드에서 셀을 클릭 할 때마다 셀에 CheckBox 컨트롤이 포함되어 있는지 확인합니다. 이 경우 않습니다 , 우리는 그 체크 박스 초점을 설정합니다 그것의 가치 토글을 .
이것은 나에게 효과가있는 것으로 보이며 훌륭하고 쉽게 재사용 가능한 솔루션입니다.
이 작업을 수행하려면 코드를 작성 해야 한다는 점에 실망합니다 . WPF에서 행을 편집 모드로 전환하는 데 사용하기 때문에 첫 번째 마우스 클릭 (DataGrid의 CheckBox에서)이 “무시”된다는 설명은 논리적으로 들릴 수 있지만 실제 환경에서는 모든 실제 응용 프로그램의 작동 방식에 위배됩니다.
화면에 체크 박스가 표시되면 한 번 클릭하여 체크 / 체크 해제 할 수 있어야합니다. 이야기의 끝.
답변
여기에는 훨씬 간단한 해결책이 있습니다.
<DataGridTemplateColumn MinWidth="20" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<CheckBox VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
DataGridCheckBoxColumn
구현 하는 데 사용 하는 경우 첫 번째 클릭은 초점을 맞추고 두 번째 클릭은 확인하는 것입니다.
그러나 DataGridTemplateColumn
구현에 사용 하려면 한 번만 클릭하면됩니다.
사용 DataGridComboboxBoxColumn
과 구현 의 차이점 DataGridTemplateColumn
도 비슷합니다.