我有一个DataGrid
,显示Employees
的一些名单信息。我添加了一个带有CheckBox
的模板列。我想从所选(KeyIDs
个选定的)行的所有行中获取CheckBox
(从DB绑定)。这些KeyIDs
我必须传递给SQL以删除选定的行(BtnDeleteSelected_Click
)。请帮忙。
这是我的DataGrid
:
<DataGrid AutoGenerateColumns="False" Grid.Row="1" Height="555" HorizontalAlignment="Left" Margin="0,5,0,0" Name="dgRosterList" VerticalAlignment="Top" Width="980" ItemsSource="{Binding}" SelectionMode="Single" SelectionUnit="FullRow" CanUserResizeColumns="True" CanUserSortColumns="True" AlternatingRowBackground="Gainsboro" AlternationCount="2" IsEnabled="True" Grid.ColumnSpan="2">
<DataGrid.Columns>
<DataGridTemplateColumn Width="30">
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox x:Name="all" Content="" Click="CheckBox_Click"/>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Checked="chkSelect_Checked" Name="chkSelect"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Sl No" Binding="{Binding SlNo}"/>
<DataGridTextColumn Header="Key ID" Binding="{Binding KeyID}" Width="80" Visibility="Hidden"/>
<DataGridTextColumn Header="Emp ID" Binding="{Binding Emp_ID}" Width="80"/>
<DataGridTextColumn Header="Emp Name" Binding="{Binding Emp_Name}" Width="200"/>
<DataGridTextColumn Header="Date" Binding="{Binding PDate, StringFormat={}{0:dd/MM/yyyy}}" Width="100"/>
<DataGridTextColumn Header="Shift" Binding="{Binding Shift_Code}" Width="80"/>
<DataGridTextColumn Header="In Time" Binding="{Binding InTime, StringFormat={}{0:hh:mm}}" Width="80"/>
<DataGridTextColumn Header="Out Time" Binding="{Binding OutTime, StringFormat={}{0:hh:mm}}" Width="80"/>
<DataGridTemplateColumn Header="Half Day" Width="80">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Name="IsHalfDay" Width="15" Height="15" Source="" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding HalfDay}" Value="Yes">
<Setter TargetName="IsHalfDay" Property="Source" Value="../Images/ico_tick.gif"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Off Day" Width="80">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Name="IsOffDay" Width="15" Height="15" Source="" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding OffDay}" Value="Yes">
<Setter TargetName="IsOffDay" Property="Source" Value="../Images/ico_tick.gif"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Delete" Width="75">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="btnDelete" Click="btnDelete_Click" Width="50" Height="20" ToolTip="Delete Roster" CommandParameter="{Binding Path=KeyID}" >
<Image Source="../Images/delete.png" Width="15" Height="19"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Processed" Binding="{Binding Processed}" Visibility="Hidden"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--<Image Source="{Binding XPath=media:thumbnail/@url}"
Width="60" Height="60"/>-->
<TextBlock Text="{Binding Path=WeeklyOffs}"/>
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
答案 0 :(得分:2)
在Event
:
private void chkSelect_Checked(object sender, RoutedEventArgs e)
{
dgRosterList.IsSynchronizedWithCurrentItem = true;
}
这将导致highlighting
当前row
,就像它被选中一样。
在XAML
中使用SelectedItem
的{{1}}属性:
DataGrid
在SelectedItem="{Binding SelectedEmployeeData}"
中,定义ViewModel
的属性:
SelectedEmployeeData
和
private DeleteViewModel m_SelectedEmployeeData;
public DeleteViewModel SelectedEmployeeData
{
get
{
return m_SelectedEmployeeData;
}
set
{
m_SelectedEmployeeData = value;
if (null != m_SelectedEmployeeData)
{
listToSend.Add(m_SelectedEmployeeData.KeyID);
}
else
{
listToSend.Remove(m_SelectedEmployeeData.KeyID);
}
OnPropertyChanged("SelectedEmployeeData");
}
}
其中List<int> listToSend = new List<int>();
将包含要发送到lstSend
的{{1}}。
此处KeyIDs
是我假设所有与列相关的属性的VM,即DB
,DeleteViewModel
等。
答案 1 :(得分:0)
您可以使用FindChild()
访问CheckBox
:
public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
{
if (parent == null)
{
return null;
}
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
T childType = child as T;
if (childType == null)
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null) break;
}
else
if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
if (frameworkElement != null && frameworkElement.Name == childName)
{
foundChild = (T)child;
break;
}
else
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null)
{
break;
}
}
}
else
{
foundChild = (T)child;
break;
}
}
return foundChild;
}
如果您只是调用此函数,它将仅返回第一个控件,但CheckBox
需要Selected Row
。要访问所选行的控件,要将事件SelectionChanged
添加到要运行的DataGrid
,这将提供Selected Row
:
<DataGrid Name="MyDataGrid" SelectionChanged="MyDataGrid_SelectionChanged">
private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
// Get the list of rows
var row_list = GetDataGridRows(MyDataGrid);
// Check the all rows
foreach (DataGridRow single_row in row_list)
{
if (single_row.IsSelected == true)
{
CheckBox MyCheckBox = FindChild<CheckBox>(single_row, "MyCheckBox"); // here your CheckBox name
MessageBox.Show(MyCheckBox.IsChecked.ToString());
}
}
}
catch
{
throw new Exception("Can't get access to DataGridRow");
}
}
GetDataGridRows()的列表:
public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource)
{
yield return null;
}
foreach (var item in itemsSource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if (null != row)
{
yield return row;
}
}
}
正如您所看到的,这种做法不是很有用,所以它不是很正确。您可以将MyChecked
的属性OnPropertyChanged()
添加到他的DataContext
。例如:
public class YourClass : INotifyPropertyChanged
{
private bool? myChecked = null;
#region INotifyPropertyChanged values
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public bool? MyChecked
{
get
{
return myChecked;
}
set
{
myChecked = value;
OnPropertyChanged("myChecked");
}
}
}
并像这样使用:
<CheckBox x:Name="MyCheckBox" IsChecked="{Binding MyChecked}" />
每次更改属性时,都会触发OnPropertyChanged()
,您可以执行某些操作。也就是说,尝试让他们的操作不在XAML
的旁边,而在数据的一侧,因为在第一种情况下,很难使用DataGrid
。
答案 2 :(得分:0)
在与每行绑定的类中定义bool属性(如IsRowSelected
),将其绑定到Ischecked
的{{1}}属性,然后删除{CheckBox
的所有行{1}}中的{1}}。