how to manipulate ItemsControl ItemTemplate - wpf

I am trying something simple but struggling to get a simple solution, just not seeing it hehe.
I have a number: “150” witch can be split in any number of segments when the user enters the segment amount in a textbox; a items control gets populated with textboxes showing the segment sizes. This works.
I want to be able to edit a segment size and then calculate the remaining sizes left to show on the other segment textboxes, but cant figure out how to do it. If someone can just point me in a direction tanks.
To show what I mean i have included a link to the project vs2010 here (49kb)

I'm unsure whether you're having trouble editing an existing segment size or whether its the re-calculation that you're having trouble with.
But one method might be to subscribe to the KeyDown event on the textbox, then check for the return key. then you could recalculate the segments , iterate the collection and update each item with the new segment.
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
TextBox textbox = sender as TextBox;
int newSegments;
if (int.TryParse(textbox.Text, out newSegments))
{
//recalculate the segments
//iterate the collection
//update the segments
}
}
}

Related

WPF User Control doesn't show up in grid

Im trying to add a UserControl in WPF to a grid, but it doesnt show up when im trying to add via MyGrid.Children.Add(UserControl). So i tried to display the number of childs of my grid and it says 1 after adding the usercontrol. (MyGrid.Children.Clear() doesn't work too. After clearing the grid it says that there are 0 childs left but there are still some UiElements when im compiling my program.)
This problem appears only in 1 function. In an other function (the same class) i can easily add childs to the same grid (myGrid).
My code:
private void AddDateOnClick(object sender, MouseButtonEventArgs e)
{
MyGrid.Children.Clear();
UserControlAddDate ucad = new UserControlAddDate();
MyGrid.Children.Add(ucad);
MessageBox.Show(MyGrid.Children.Count.ToString()); //Only to test if there are some childs
}
When i try to clear this grid in a other function (same class) it clears the grid. Only clearing in this function is a problem. Im not understanding why???
What is this UserControlAddDate? Maybe it is not initialized. That’s why it’s not getting added to the grid..
In that place try to add a textbox to the grid and check if it’s working. If it’s working then it’s the problem with your code.
As mentioned by Ed Plunkett, please try to use templates and databinding. It's the best way to work with WPF.
Try this anyway.
private void AddDateOnClick(object sender, MouseButtonEventArgs e)
{
MyGrid.Children.Clear();
TextBox ucad = new TextBox();
ucad.Text = “TEST”;
MyGrid.Children.Add(ucad);
MessageBox.Show(MyGrid.Children.Count.ToString()); //Only to test if there are some childs
}

WPF - Get current cell details

I have a grid which contains 2 rows and 2 columns. Each cell hosting a windows forms host control. I want to capture the selected cell when the user clicks on any of the cell. I have searched and found that there is no 'Click' event but I can make use of 'MouseDown' event with similar results. But now I am stuck because you would think there must be an easier way like 'GetCurentRow' and 'GetCurrentColumn' to capture the selected cell but there isn't.
What I want further to do is to get the child element in that particular cell of the grid.
I tried the following code but no matter which cell I click, I always get 0 for the row and column:
void InnerGridToContainWindowsFormsHost_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var element = (UIElement)e.Source;
int c = Grid.GetColumn(element);
int r = Grid.GetRow(element);
}
Is there any way to get the selected/clicked cell details or the children inside the cell?
I think that you may be going down the wrong route here... if you just want to know what control was clicked on, try using the VisualTreeHelper.HitTest method. You can find information on the VisualTreeHelper.HitTest Method page on MSDN. Basically, you would do something like:
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Get the position of the mouse pointer relative to the grid
Point clickPoint = e.GetPosition(grid);
HitTestResult result = VisualTreeHelper.HitTest(grid, clickPoint);
if (result != null)
{
// Do something here
}
}
You may also need some kind of basic recursive function to drill down through the Visual objects until you get to the one you want.

richtextbox binding

I have 2 RichTextBoxes (rtb1, rtb2), I something wrote in rtb1 and click on enter key, on this event is added text from rtb1 to rtb2. I solved this in code behind, it is possible this same write in XAML?
C# code:
private void rtb2_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
var textElement = new Run() { Text = rtb2.Text };
var paragraph = new Paragraph();
paragraph.Inlines.Add(textElement);
rtb1.Document.Blocks.Add(paragraph);
rtb2.Document.Blocks.Clear();
//On this place I would like set start position for input text in rtb2 richtextbox on the start position
}
}
Thank for your advances.
If you really need your combined RichTextBox to have generalized document editing capabilities, what you are doing is probably the easiest and no, there is no pure-XAML way to do it.
On the other hand, if you are writing a chat application or something like it there may be a much better way to do it: Replace your combined RichTextBox with an ItemsControl that displays all the chat items as individual items. Then when Enter is pressed, add the text to a collection in your model. As long as the collection implements INotifyCollectionChanged, the new text will appear in your ItemsControl. And if the template you use for your ItemsControl allows editing, your user will be able to edit the item.
Which way you go all depends on what you're trying to accomplish.

Silverlight 4 - Print Items Control

I am building a Silverlight 4 application. This application is going to print the contents of an ItemsControl. This ItemsControl uses an ItemTemplate to render the items bound to the control. In all, I have 500 items that are bound to the control.
Oddly, when I attempt to print the ItemsControl, it seems to cut off after a certain point. I cannot tell when it gets cut off. I just know that it gets cut off. I have a hunch it has something to do with virtualization. However, I'm not sure how to overcome this. Currently, I'm printing the ItemsControl like such:
private void printHyperlink_Click(object sender, RoutedEventArgs e)
{
PrintDocument printDocument = new PrintDocument();
printDocument.BeginPrint +=
new EventHandler<BeginPrintEventArgs>(printDocument_BeginPrint);
printDocument.PrintPage +=
new EventHandler<PrintPageEventArgs>(printDocument_PrintPage);
printDocument.EndPrint +=
new EventHandler<EndPrintEventArgs>(printDocument_EndPrint);
printDocument.Print("My Items");
}
void printDocument_BeginPrint(object sender, BeginPrintEventArgs e)
{}
void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{ e.PageVisual = myItemsControl; }
void printDocument_EndPrint(object sender, EndPrintEventArgs e)
{}
What am I doing wrong? How do I ensure that all of the items in my ItemsControl are printed as they are rendered?
The printing APIs don't automatically paginate items in an ItemsControl for you. Furthermore, if you are printing something that is already in the visual tree, the result may get clipped to match what is being rendered in the window at the time of printing.
To print multiple pages, you'll need to:
Measure to figure out how many items to show on the page
Create visuals that only show the items you want on that page
Pass them into your "e.PageVisual"
Set e.HasMorePages to be true until you're on the last page
All in all, this can be a fair amount of work. If you're just trying to print an ItemsControl with an ItemTemplate, you'll have to do all of the work above. For slightly more sophisticated scenarios (e.g. adding page numbers, headers/footers, etc.), there's even more work to do.
That said, it's possible to build a library over the simple Silverlight printing APIs that does something like this. I recently blogged a control meant to address exactly this scenario (as well as some of the more sophisticated ones).
http://www.davidpoll.com/2010/04/16/making-printing-easier-in-silverlight-4/

How can I put a Silverlight 3 DataGridCell into edit mode in code?

I want to be able to pick a specific cell in a Silverlight 3.0 DataGrid and put it into edit mode. I can use the VisualTreeManager to locate the cell. How do I switch to edit mode?
Each DataGridCell looks like this in the VisualTreeManager:
System.Windows.Controls.DataGridCell
System.Windows.Controls.Grid
System.Windows.Shapes.Rectangle
System.Windows.Controls.ContentPresenter
System.Windows.Controls.TextBlock
System.Windows.Shapes.Rectangle
System.Windows.Shapes.Rectangle
with the TextBlock containing the text I want to edit.
Update
Following #AnthonyWJones' suggestion, here's how I tried to do this using BeginEdit().
I wanted to keep it simple so I thought I'd pick a column in the first row. Even that proved beyond my SL knowledge! In the end, I get the first row by creating a field called firstRow to hold it:
private DataGridRow firstRow;
added a LoadingRow handler to the DataGrid:
LoadingRow="computersDataGrid_LoadingRow"
and
private void computersDataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
if (this.firstRow == null)
this.firstRow = e.Row;
}
and then adding a button to the panel to trigger the edit:
private void Button_Click(object sender, RoutedEventArgs e)
{
this.dataGrid.SelectedItem = this.firstRow;
this.dataGrid.CurrentColumn = this.dataGrid.Columns[4];
this.dataGrid.BeginEdit();
}
I click the button and the correct cell is selected but it doesn't go into edit on the cell. It takes a manual click to achieve that.
I'm not sure why you need to find the DataGridCell using VisualTreeManager nor do I know currently how you would properly start editing . You may get away with simply setting the cell's visual state to editing.
VisualStateManager.GoToState(myDataGridCell, "Editing", true);
I'm not sure how the grid behaves when you do something like the above. You may find things goe a bit pearshaped if you need DataGrid to help you revert changes to a row.
The "standard" approach would be to set the DataGrid SelectedItem property to the item represented by the row, set the CurrrentColum property to the DataGridColumn object that represents to the column in which the cell is found. Then call the BeginEdit method.
I am not able to understand your problem properly, but I had a similar problem
I wanted to make only few of the Grid Cells editable and rest were not. Instead of creating a logic and assigning ReadOnly as true/ false, I did the simple thing.
Mark the whole Grid's cells are writable, IsReadOnly as false
Set the event PreparingCellForEdit and send a callback
When you double click on a cell, it gets in the edit mode
Check whether this cell you want to be editable
If it is allowed to be edited, go ahead
If that cell is ReadOnly, then call CancelEdit
The sample code goes like
namespace foo
{
public class foobar
{
public foobar()
{
sampleGrid = new DataGrid();
sampleGrid.IsReadOnly = false;
sampleGrid.PreparingCellForEdit += new EventHandler<DataGridPreparingCellForEditEventArgs>(sampleGrid_PreparingCellForEdit);
}
void sampleGrid_PreparingCellForEdit(object sender, DataGridsampleGrid_PreparingCellForEditEventArgs e)
{
if (sampleGrid.SelectedItem != null)
{
bool isWritableField = CheckIfWritable()
if (isWritableField == false)
{
sampleGrid.CancelEdit();
}
// continue with your logic
}
}
private DataGrid sampleGrid;
}
}

Resources