Context Menu on a Group Row in RadGridView - silverlight

I found one old solution Here.
But GridViewExpander is obsolete in 2009. Proof Here.
How can i implement it (Context Menu on a Group Row in RadGridView) in another way?

No answers... =(
But i found solution.
The are two ways to solve it:
1) If you need custom style for your GridViewGroupRow - read about Templates Structure
2) If not, then just use somthing like this:
<TelerikNavigation:RadContextMenu.ContextMenu>
<TelerikNavigation:RadContextMenu Opened="RadContextMenuOpened" ItemClick="ContextMenuItemClick" x:Name="contextMenu">
</TelerikNavigation:RadContextMenu>
private void RadContextMenuOpened(object sender, RoutedEventArgs e)
{
var menu = (RadContextMenu)sender;
if (menu == null)
return;
var cell = menu.GetClickedElement<GridViewCell>();
var row = menu.GetClickedElement<GridViewRow>();
var groupRow = menu.GetClickedElement<GridViewGroupRow>();
if (cell != null && row != null)
{
if (!cell.DataColumn.IsFrozen)
{
//Code for current cell
}
}
if (groupRow != null)
{
//Code for groupRow
}
}
private void ContextMenuItemClick(object sender, RadRoutedEventArgs e)
{
if (_currentCell != null)
{
//Code for current cell
}
if (_currentGroupRow != null)
{
var menu = (RadContextMenu)sender;
var clickedItem = e.OriginalSource as RadMenuItem;
if (clickedItem != null)
{
foreach (var gridViewRow in _currentGroupRow.ChildrenOfType<GridViewRow>())
{
foreach (var gridViewCellBase in gridViewRow.Cells)
{
if (gridViewCellBase.Column.UniqueName == "PlanObject")
{
var val = gridViewCellBase.DataContext as YourObjectName;
if (val != null)
{
//.....
}
}
}
}
//....
}
}
}

Related

InvalidCastException when remove item in ObservableCollection

I am doing a project using WPF and Prims.
When remove category in Categories, an error has occurred.
public ObservableCollection<CategoryModel> _categories;
public ObservableCollection<CategoryModel> Categories
{
get { return _categories; }
set
{
SetProperty(ref _categories, value);
}
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
_journal = navigationContext.NavigationService.Journal;
var category = navigationContext.Parameters["categoryAdd"] as CategoryModel;
if (category != null)
Categories.Add(category);
category = navigationContext.Parameters["categoryDelete"] as CategoryModel;
if (category != null)
{
foreach(var elm in Categories)
if (elm.Id == category.Id)
Categories.Remove(elm); //⇒Error here
}
}
Error:
System.InvalidCastException: 'Cannot cast an object of type' System.Windows.Controls.SelectionChangedEventArgs' to type 'SaleManager.Wpf.Admin.Models.CategoryModel'. '
Why does this error occur? How to fix it?
You can't change a collection in a foreach while reading this collection.
you can do this:
var item = Categories.FirstOrDefault(elm=> elm.Id == category.Id);
Categories.Remove(item);
Use a for loop and iterate backwards. elm is supposed to be a CategoryModel:
if (category != null)
{
for (int i = Categories.Count - 1; i >= 0; --i)
{
CategoryModel elm = Categories[i];
if (elm.Id == category.Id)
{
Categories.Remove(elm);
}
}
}

DataGridComboboxColumn - Get cell value

The task is the following: there is a DataGrid with ComboboxColumns. If user changes cell[2,3] and selected value!=0 then disable cell[3,2]. I wrote the following Handler:
private void grAssessment_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
int x = e.Column.DisplayIndex;
int y = e.Row.GetIndex();
grAssessment.GetCell(x, y).IsEnabled = false;
grAssessment.GetCell(x, y).Background = Brushes.LightGray;
}
But it disables appropriate cell in anyway. How to add selected value!=0 condition to this code?
Thanks in advance.
Try to check this out:
1. DataGridComboBoxColumn ItemsSource (for current version only, use your own):
private ObservableCollection<ScoreData> _scores = new ObservableCollection<ScoreData>(
new List<ScoreData>
{
new ScoreData{Score = 1, ScoreVerbal = "the same"},
new ScoreData{Score = 3, ScoreVerbal = "moderate superiority"},
new ScoreData{Score = 5, ScoreVerbal = "strong superiority"},
new ScoreData{Score = 7, ScoreVerbal = "the samvery strong superioritye"},
new ScoreData{Score = 9, ScoreVerbal = "extremely superiority"},
} );
2. Handler code (the handler defined on the data grid):
private void SelectDataGrid_OnCellEditEnding(object sender,
DataGridCellEditEndingEventArgs e)
{
var editingElement = e.EditingElement as Selector;
if(editingElement == null) return;
var selectedData = editingElement.SelectedItem as ScoreData;
if(selectedData == null || selectedData.Score > 1) return;
var dataGridCell = editingElement.GetVisualParentOfType<DataGridCell>();
if(dataGridCell == null) return;
dataGridCell.IsEnabled = false;
}
3. GetVisualParentOfType code (as part of extension class):
public static class VisualTreeExtensions
{
public static T GetVisualParentOfType<T>(this DependencyObject child)
where T : DependencyObject
{
if (child is T)
return child as T;
var parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null) return null;
var parent = parentObject as T;
return parent ?? GetVisualParentOfType<T>(parentObject);
}
public static T GetChildOfType<T>(this DependencyObject depObj)
where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
}
regards,
I found the following solution
private void grAssessment_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
int x = e.Column.DisplayIndex;
int y = e.Row.GetIndex();
DataGridCell cell = grAssessment.GetCell(y, x);
if (((System.Windows.Controls.ComboBox)(cell.Content)).Text != "")
{
grAssessment.GetCell(x, y).IsEnabled = false;
grAssessment.GetCell(x, y).Background = Brushes.LightGray;
}
else
{
grAssessment.GetCell(x, y).IsEnabled = true;
grAssessment.GetCell(x, y).Background = Brushes.White;
}
}

Use Kinect to create a digital catalog application

I am creating a WPF application to create digital catalog using kinect v1.8. I am trying to track only a single skeleton using following code:-
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
// Even though we un-register all our event handlers when the sensor
// changes, there may still be an event for the old sensor in the queue
// due to the way the KinectSensor delivers events. So check again here.
if (this.KinectSensor != sender)
{
return;
}
SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame();
if (skeletonFrame == null)
return;
Skeleton[] skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
Skeleton skeleton = (from skl in skeletons
where skl.TrackingState == SkeletonTrackingState.Tracked
select skl).FirstOrDefault();
if (skeleton == null)
return;
Skeleton[] s = new Skeleton[1];
s[0] = skeleton;
if (SkeletonTrackingState.Tracked == s[0].TrackingState)
{
//s1.SkeletonStream.ChooseSkeletons(s[0].TrackingId);
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
this.interactionStream.ProcessSkeleton(s, accelerometerReading, skeletonFrame.Timestamp);
}
}
I am getting an exception when I run the code and skeleton gets detected as follows:-
on the line "this.interactionStream.ProcessSkeleton(s, accelerometerReading, skeletonFrame.Timestamp);"
I need to detect only one skeleton and use it for further processing like to access the digital catalog applications.
Thanks in advance.
I have Faced Same Problem By using below code I have track only one skeleton Which is closer to the sensor.and directly assign the closest skeleton to the main skeleton stream.
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame())
{
if (skeletonFrame != null && this.skeletons != null)
{
//Console.WriteLine(skeletonFrame.SkeletonArrayLength);
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
// Set skeleton datas from skeletonFrame
skeletonFrame.CopySkeletonDataTo(this.skeletons);
TrackClosestSkeleton();
Skeleton[] singleSkeleton = new Skeleton[6];
Skeleton skl=(from mno in this.skeletons where mno.TrackingState==SkeletonTrackingState.Tracked && mno.TrackingId==globalClosestID select mno).FirstOrDefault();
if (skl == null)
return;
//Creating an empty skkeleton
Skeleton emptySkeleton = new Skeleton();
singleSkeleton[0] = skl; //Pass the Tracked skeleton with closestID
singleSkeleton[1] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[2] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[3] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[4] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[5] = emptySkeleton; //Passing Empty Skeleton
this.snew.SkeletonStream.ChooseSkeletons(globalClosestID);
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
this.interactionStream.ProcessSkeleton(singleSkeleton, accelerometerReading, skeletonFrame.Timestamp);
}
}
}
int globalClosestID = 0;
private void TrackClosestSkeleton()
{
if (this.snew != null && this.snew.SkeletonStream != null)
{
if (!this.snew.SkeletonStream.AppChoosesSkeletons)
{
this.snew.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
}
float closestDistance = 10000f; // Start with a far enough distance
int closestID = 0;
foreach (Skeleton skeleton in this.skeletons.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skeleton.Position.Z < closestDistance)
{
closestID = skeleton.TrackingId;
closestDistance = skeleton.Position.Z;
}
}
if (closestID > 0)
{
this.snew.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
globalClosestID = closestID;
}
}
}
check the above code it works for me.It may helpful to you.Here snew is the Kinectsensor.
You should try to track the closest skeleton using this method from MSDN
private void TrackClosestSkeleton()
{
if (this.kinect != null && this.kinect.SkeletonStream != null)
{
if (!this.kinect.SkeletonStream.AppChoosesSkeletons)
{
this.kinect.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
}
float closestDistance = 10000f; // Start with a far enough distance
int closestID = 0;
foreach (Skeleton skeleton in this.skeletonData.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skeleton.Position.Z < closestDistance)
{
closestID = skeleton.TrackingId;
closestDistance = skeleton.Position.Z;
}
}
if (closestID > 0)
{
this.kinect.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
}
}
}
And then in your SkeletonFrameReady
private void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null && this.skeletonData != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
// Set skeleton datas from skeletonFrame
skeletonFrame.CopySkeletonDataTo(this.skeletonData);
TrackClosestSkeleton();
}
}
//Do some stuff here
}

wpf richtextbox check if caret is in the last line or count how many lines it has

I am trying to find out in a richtext box whether the caret is position in the last line. Is this possible?
NOTE: At the end I also added: or count how many lines it has, this is because in the miscrosoft forum there is an example for detecting in which line the caret is.
thanks
Please verify the msdn link
http://social.msdn.microsoft.com/Forums/en/wpf/thread/667b5d2a-84c3-4bc0-a6c0-33f9933db07f
If you really wanted to know the line number of the caret, you could do something like the following (probably needs some tweaking):
TextPointer caretLineStart = rtb.CaretPosition.GetLineStartPosition(0);
TextPointer p = rtb.Document.ContentStart.GetLineStartPosition(0);
int caretLineNumber = 1;
while (true)
{
if (caretLineStart.CompareTo(p) < 0)
{
break;
}
int result;
p = p.GetLineStartPosition(1, out result);
if (result == 0)
{
break;
}
caretLineNumber++;
}
The code to get the number of lines:
Int32 CountDisplayedLines(RichTextBox rtb)
{
Int32 result = -1;
rtb.CaretPosition = rtb.Document.ContentStart;
while (rtb.CaretPosition.GetLineStartPosition(++result) != null)
{
}
return result;
}
I have found a solution. Maybe there is a simpler way, if so please let me know
private void OnHasRtbReachedEnd(System.Windows.Controls.RichTextBox rtb)
{
TextPointer pointer1 = rtb.CaretPosition;
int iCurrentLine = GetLineNumber(rtb);
rtb.CaretPosition = rtb.Document.ContentEnd;
int iLastLine = GetLineNumber(rtb);
if (iCurrentLine == iLastLine)
{
if (!_bIsRtbMovingUpDown)
MoveToNextDataGridRow();
_bIsRtbMovingUpDown= false;
}
else
{
_bIsRtbMovingUpDown= true;
}
rtb.CaretPosition = pointer1;
}
//This code comes from
//http://social.msdn.microsoft.com/Forums/en/wpf/thread/667b5d2a-84c3-4bc0-a6c0-33f9933db07f
private int GetLineNumber(System.Windows.Controls.RichTextBox rtb)
{
TextPointer caretLineStart = rtb.CaretPosition.GetLineStartPosition(0);
TextPointer p = rtb.Document.ContentStart.GetLineStartPosition(0);
int caretLineNumber = 1;
while (true)
{
if (caretLineStart.CompareTo(p) < 0)
{
break;
}
int result;
p = p.GetLineStartPosition(1, out result);
if (result == 0)
{
break;
}
caretLineNumber++;
}
return caretLineNumber;
}
I tried the code and is not giving correct results always.
One smart way to do it is this
int previousCursorPosition;
private void RichTarget_KeyDown_1(object sender, KeyEventArgs e)
{
if (e.Key == Key.Up || e.Key == Key.Down)
{
Xceed.Wpf.Toolkit.RichTextBox rich = (Xceed.Wpf.Toolkit.RichTextBox)sender;
previousCursorPosition = rich.CaretPosition.GetOffsetToPosition(rich.CaretPosition.DocumentStart);
}
}
private void RichTextBox_KeyUp_1(object sender, KeyEventArgs e)
{
if (e.Key == Key.Up)
{
Xceed.Wpf.Toolkit.RichTextBox rich = (Xceed.Wpf.Toolkit.RichTextBox)sender;
if (previousCursorPosition == rich.CaretPosition.GetOffsetToPosition(rich.CaretPosition.DocumentStart))
{
//do your staff
}
}
else if (e.Key == Key.Down)
{
Xceed.Wpf.Toolkit.RichTextBox rich = (Xceed.Wpf.Toolkit.RichTextBox)sender;
if (previousCursorPosition == rich.CaretPosition.GetOffsetToPosition(rich.CaretPosition.DocumentStart))
{
//do your staff
}
}
}

BeginEdit of a specific Cell from code behind

Is possibile begin edit of a specific cell from code behind with DataGrid control (WPF Toolkit)?
I have to enable the celledittemplate of first cell of selected row after a button action...how can I do?
pls, try putting the code below in your button's on click event handler:
DataGridCell cell = GetCell(1, 0);
if (cell != null)
{
cell.Focus();
yourDataGrid.BeginEdit();
}
below is implementation for the GetCell method taken from here Grabing controls from a DataGrid
public DataGridCell GetCell(int row, int column)
{
DataGridRow rowContainer = GetRow(row);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
// try to get the cell but it may possibly be virtualized
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
if (cell == null)
{
// now try to bring into view and retreive the cell
gridPersons.ScrollIntoView(rowContainer, gridPersons.Columns[column]);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
}
return cell;
}
return null;
}
public DataGridRow GetRow(int index)
{
DataGridRow row = (DataGridRow)gridPersons.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// may be virtualized, bring into view and try again
gridPersons.ScrollIntoView(gridPersons.Items[index]);
row = (DataGridRow)gridPersons.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
static T GetVisualChild<T>(Visual parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
hope this helps, regards

Resources