Hi,
I have a fairly simple scenario that I am having trouble with. I have a custom data annotation as shown below. It just makes sure that at least one item in my collection has it's IsSelected flag set. This collection is bound to an ItemsControl of checkboxes. The xaml is at the bottom. The validation works correctly but the error message displayed in summary at the bottom if the form is not red and is prefixed with a colon. Is there a way to make this a little better and more consistent with "normal" dataannotation validations so that the ItemsControl or containing stackpanel is highlighted in a similar fashion as a textbox might be highlighted?
Thanks ... Ed
public class HasOneItem : ValidationAttribute{ public HasOneItem() {} protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value != null) { ObservableCollection<SampleTechniqueInfo> sti = (ObservableCollection<SampleTechniqueInfo>)value; if ((from a in sti where a.IsSelected == true select a).Count() == 0) { var errorMessage = FormatErrorMessage(validationContext.DisplayName); return new ValidationResult(errorMessage); } } return ValidationResult.Success; }}
<StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="2" Grid.RowSpan ="5"> <Label Content="Associated Techniques:" HorizontalAlignment="Left" HorizontalContentAlignment="Left" Width="350" Height="auto"/> <StackPanel Orientation="Vertical" MaxHeight="210" > <ItemsControl x:Name ="lstTechniques" ItemsSource="{Binding AssociatedTechniques }" Margin="5,0,0,0" > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <support:UniformGridWithOrientation Orientation="Vertical" Columns="4" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate > <CheckBox Content="{Binding TechniqueAbbr}" IsChecked="{Binding IsSelected, Mode=TwoWay}" ToolTip="{Binding TechniqueName}" > </CheckBox> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel></StackPanel>From the drag drop examples on the site, the dragging and dropping within and between grid views is more or less working how we want. But I would like to change the icon in the visual associated with the "effect" and I can't seem to figure out how and where to do it. We have a content template but that only affects the rest of the visual and not the "effect" portion of it.
I tried inheriting from the DragVisual but there are so many overridable things within I can't tell what is needed to be done. One thing however that was particularly interesting, is that when I inherit from the DragVisual but do not override anything within, the "move" icon is gray instead of blue.
I am trying to achieve displaying a delete icon if the user drags an item outside of the grid to indicate that the item will be removed rather than the "no" icon which implies that the action will have no result. Please advise if there is a simpler way to do this.
Hello Telerik,
During a Drag&Drop in a RadTreeView, I encounter some troubles with TreeViewDragDropOptions where the dropped item is positioned. Ideally I would like to get the objects that are positioned before and after (if they exist) the dropped item.
However, following multiple found example (like this one), in my case, the content of TreeViewDragDropOptions is always null.
Those are the objects I am binding to the TreeView:
Node.cs
public class Node<T>{ public T Source { get; set; } public Node<T> Parent { get; set; } public List<Node<T>> Children = new List<Node<T>>();}
Here T is a Category
Category.cs
public class Category{ public string Title { get; set; } public int Sort { get; set; }}
In the ViewModel, an ObservableCollection contains the hierarchy.
public ObservableCollection<Node<Category>> MyCategories{ [...]}
Finally, the Views:
MyView.xaml
<telerik:RadTreeListView Name="CategoriesRadTreeView" IsDragDropEnabled="True" telerik:TreeViewSettings.DragDropExecutionMode="New" ItemsSource="{Binding MyCategories}" AutoGenerateColumns="False"> <telerik:RadTreeListView.ChildTableDefinitions> <telerik:TreeListViewTableDefinition ItemsSource="{Binding Children}" /> </telerik:RadTreeListView.ChildTableDefinitions> <telerik:RadTreeListView.SortDescriptors> <telerik:SortDescriptor Member="Source.Sort" SortDirection="Ascending" /> </telerik:RadTreeListView.SortDescriptors> <telerik:RadTreeListView.Columns> <telerik:GridViewDataColumn DataMemberBinding="{Binding Source.Title}" Header="Title" /> <telerik:GridViewDataColumn DataMemberBinding="{Binding Source.Sort}" Header="Sort" /> </telerik:RadTreeListView.Columns></telerik:RadTreeListView>
And the code behind:
MyView.xaml.cs
public WebstoreKatalogView(){ InitializeComponent(); DragDropManager.AddDragInitializeHandler(CategoriesRadTreeView, OnDragInitialize); DragDropManager.AddDragOverHandler(CategoriesRadTreeView, OnDragOver, true); DragDropManager.AddDropHandler(CategoriesRadTreeView, OnDrop);}private void OnDragInitialize(object sender, DragInitializeEventArgs e){ e.AllowedEffects = DragDropEffects.All; var payload = DragDropPayloadManager.GeneratePayload(null); var data = ((FrameworkElement)e.OriginalSource).DataContext; payload.SetData("DragData", data); e.Data = payload; e.Handled = true;}private void OnDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e){ var options = DragDropPayloadManager.GetDataFromObject(e.Data, TreeViewDragDropOptions.Key) as TreeViewDragDropOptions; if (options != null) { // never reaches here! }}private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e){ // this works! var node = DragDropPayloadManager.GetDataFromObject(e.Data, "DragData");}
I have no idea what is wrong or what could be missing.
Thank you very much for your help!
Sylvain
I've tried all the options for KeyboardNavigation.TabNavigation and none of them seem to get the desired result. How to enable tabbing through fields of a RadDataForm displayed via a RadGridView row details template?
Thanks ... Ed


Hi
I've added a button to my RadGridView via the below:
Dim col As New MyDeleteButtonColumn()
RadGridView1.Columns.Add(col)
Public Class MyDeleteButtonColumn
Inherits Telerik.Windows.Controls.GridViewColumn
Public Overrides Function CreateCellElement(cell As GridViewCell, dataItem As Object) As FrameworkElement
Dim btn As New RadButton()
btn.Content = "MD"
btn.[AddHandler](Button.ClickEvent, New RoutedEventHandler(AddressOf btn_Click))
Return btn
End Function
Private Sub btn_Click(sender As Object, e As RoutedEventArgs)
Dim win2 As New form2("gvcell0value:)")
win2.Show()
End Sub
Within the but_Click I need to get the value of from cell 0 to pass throught to a new form opening
How could I achive this?
Many thanks
Lets assume that the view is the following:
<Window x:Class="RadGridViewSelectionBug.MainWindow" xmlns:local="clr-namespace:RadGridViewSelectionBug" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" WindowState="Maximized"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> </Grid.RowDefinitions> <Button HorizontalAlignment="Left" Click="Button_Click">Click Me</Button> <telerik:RadGridView x:Name="radGridView" Grid.Row="1" NewRowPosition="None" RowIndicatorVisibility="Collapsed" ItemsSource="{Binding DataView}" ShowGroupPanel="False" AutoGenerateColumns="True" IsReadOnly="True" IsFilteringAllowed="False" EnableColumnVirtualization="True" CanUserSortColumns="False" CanUserDeleteRows="False" CanUserInsertRows="False" SelectionMode="Extended" SelectionUnit="Cell" MinColumnWidth="50" CanUserReorderColumns="False" CanUserFreezeColumns="False" GroupRenderMode="Flat" ValidatesOnDataErrors="None" ColumnWidth="75" FrozenColumnCount="1" FrozenColumnsSplitterVisibility="Collapsed" ClipboardCopyMode="Cells" ClipboardPasteMode="Cells" TextBlock.TextAlignment="Center"> </telerik:RadGridView> </Grid></Window>
The Code behind is the following:
public partial class MainWindow : Window{ public MainWindow() { InitializeComponent(); this.DataContext = new MainViewModel(); radGridView.SelectedCellsChanged += RadGridView_SelectedCellsChanged; } private void RadGridView_SelectedCellsChanged(object sender, Telerik.Windows.Controls.GridView.GridViewSelectedCellsChangedEventArgs e) { var selectedCells = (sender as RadGridView).SelectedCells.Where(c => c != null).ToList(); if (selectedCells.Any()) { var firstCell = selectedCells.First(); var lastCell = selectedCells.Last(); int fromRowIndex = firstCell.Column.DataControl.Items.IndexOf(firstCell.Item); int fromColIndex = firstCell.Column.DisplayIndex; int toRowIndex = lastCell.Column.DataControl.Items.IndexOf(lastCell.Item); int toColIndex = lastCell.Column.DisplayIndex; Console.WriteLine(string.Format("{0}, {1}, {2}, {3}", fromRowIndex, fromColIndex, toRowIndex, toColIndex)); } } private void Button_Click(object sender, RoutedEventArgs e) { (this.DataContext as MainViewModel).RebuildData(); }}
And the MainViewModel code is:
public class MainViewModel : ViewModelBase{ private DataTable _dataTable; public MainViewModel() { _dataTable = new DataTable(); _dataTable.Columns.Add(new DataColumn() { Caption = "Col1", DataType = typeof(int), }); _dataTable.Columns.Add(new DataColumn() { Caption = "Col2", DataType = typeof(int), }); _dataTable.Columns.Add(new DataColumn() { Caption = "Col3", DataType = typeof(int), }); for (int i = 0; i <100; i++) { var row = _dataTable.NewRow(); for (int j = 0; j < 3; j++) { row[j] = 0; } _dataTable.Rows.Add(row); } } internal void RebuildData() { var dataTable = new DataTable(); dataTable.Columns.Add(new DataColumn() { Caption = "Col1", DataType = typeof(int), }); dataTable.Columns.Add(new DataColumn() { Caption = "Col2", DataType = typeof(int), }); dataTable.Columns.Add(new DataColumn() { Caption = "Col3", DataType = typeof(int), }); for (int i = 0; i < 10; i++) { var row = dataTable.NewRow(); for (int j = 0; j < 3; j++) { row[j] = 0; } dataTable.Rows.Add(row); } DataTable = dataTable; } public DataView DataView { get { return _dataTable.DefaultView; } } public DataTable DataTable { get { return _dataTable; } set { _dataTable = value; OnPropertyChanged("DataView"); } }}
Run the code. Then Press Ctrl + A, in order to select all cells.
Then click on the Button.
You should get an exception (The grid view code tries to access a column with index that does not exist).
If I remove the cellInfo null check, and just write:
var selectedCells = (sender as RadGridView).SelectedCells;
Then I'll get that few cells in the SelectedCells are nulls (I might get that the firstCell, or the lastCell are nulls).
Now for another interesting bug:
Restart the code.
Select the first cell (upper left corner). The code shows Row = 0 and Col = 0 --> Good.
Now Click the button.. The selection is cleared...
Now Select the first cell again. The code shows Row = -1, Col = 0. (WTF?)
Now, any cell that you will select on the first row will give you that result. But if you select a cell from a different row, and then reselect a cell from the first row, then the problem is fixed.
Btw, getting the Item from the Added cells and checking its row index does give the correct result, but what I'm trying to do is to have the user have only 1 selected region (A rectangle of selected cells), so I can have a from row, from cell, to row, and to cell information.
So, in my code, I also clear selection in Grid PreviewMouseLeftButtonDown.
Any other suggestions of having only rectangular selection will be welcome (since right now, clicking on blank area, or clicking the scrollbar also clears the selection).
Furthermore, any suggestions on how to get the correct selected region will be welcome.
Thanks