I have the following coding where I bind a CheckBox and TextBlock into one DataGridTemplateColumn.
Would it be possible for me to edit the cell with the checkbox and textbox when I click on the cell itself to edit the text inside of it? I still want to be able to set my CheckBox to true or false at the same time as editing the text within the textblock.
Here is my coding:
private void btnFeedbackSelectSupplier_Click(object sender, RoutedEventArgs e)
{
DataGridTemplateColumn columnFeedbackSupplier = new DataGridTemplateColumn();
columnFeedbackSupplier.Header = "Supplier";
columnFeedbackSupplier.CanUserReorder = true;
columnFeedbackSupplier.CanUserResize = true;
columnFeedbackSupplier.IsReadOnly = false;
//My stack panel where I will host the two elements
var stackPanel = new FrameworkElementFactory(typeof(StackPanel));
stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
DataTemplate cellTemplate = new DataTemplate();
//Where I create my checkbox
FrameworkElementFactory factoryCheck = new FrameworkElementFactory(typeof(CheckBox));
Binding bindCheck = new Binding("TrueFalse");
bindCheck.Mode = BindingMode.TwoWay;
factoryCheck.SetValue(CheckBox.IsCheckedProperty, bindCheck);
stackPanel.AppendChild(factoryCheck);
//Where I create my textblock
FrameworkElementFactory factoryText = new FrameworkElementFactory(typeof(TextBlock));
Binding bindText = new Binding("Supplier");
bindText.Mode = BindingMode.TwoWay;
factoryText.SetValue(TextBlock.TextProperty, bindText);
stackPanel.AppendChild(factoryText);
cellTemplate.VisualTree = stackPanel;
columnFeedbackSupplier.CellTemplate = cellTemplate;
DataGridTextColumn columnFeedbackSupplierItem = new DataGridTextColumn();
columnFeedbackSupplier.Header = (cmbFeedbackSelectSupplier.SelectedItem as DisplayItems).Name;
dgFeedbackAddCost.SelectAll();
IList list = dgFeedbackAddCost.SelectedItems as IList;
IEnumerable<ViewQuoteItemList> items = list.Cast<ViewQuoteItemList>();
var collection = (from i in items
let a = new ViewQuoteItemList { Item = i.Item, Supplier = i.Cost, TrueFalse = false }
select a).ToList();
dgFeedbackSelectSupplier.Columns.Add(columnFeedbackSupplier);
dgFeedbackSelectSupplier.ItemsSource = collection;
}
My example of how it looks now and how I would like to edit that R12 value inside the cell, while still being able to set the checkbox to true or false.
As for my original question, YES you can edit the cell with a CheckBox inside, but instead of a TextBlock I used a TextBox and I changed my the following coding from my question:
var stackPanel = new FrameworkElementFactory(typeof(StackPanel));
stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);//Delete this line
To
var dockPanel = new FrameworkElementFactory(typeof(DockPanel));
Because a StackPanel does not have support for certain elements (like a TextBox) to fill the remaining available space, where a DockPanel does have support for it.
And then I added this line to make my TextBox fill the remaining space availble
factoryText.SetValue(TextBox.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
Hope this will help someone else out there :)
Why do you want to use TextBlock instead of TextBox ? If you want to expand the full width of my column length, then just set HorizontalAlignment to Stretch like that:
FrameworkElementFactory factoryText = new FrameworkElementFactory(typeof(TextBox));
factoryText.Text = HorizontalAlignment.Stretch;
Update:
And put your TextBox into Grid or DockPanel; as Zach Johnson says that StackPanel is meant for "stacking" things even outside the visible region, so it won't allow you to fill remaining space in the stacking dimension.
Related
I am trying to center a column in a ListView in the code-behind. Since the columns are dynamically created during runtime, there is no option to do this in the XAML.
Here the helper I created. Setting the other properties like font color works fine - any ideas?
private void ListViewHelper(GridView gridView, ListView listView, MatrixId assignment, string key, IValueConverter converter)
{
// new column
GridViewColumn gridViewColumn = new GridViewColumn();
// header text and formating
gridViewColumn.Header = new TextBlock { Text = assignment.Id.ToString(), TextAlignment = TextAlignment.Center, Padding = new Thickness(7, 0, 0, 0), Width = 50 };
// databinding & converter
FrameworkElementFactory frameworkElementFactory = new FrameworkElementFactory(typeof(TextBlock));
DataTemplate dataTemplate = new DataTemplate();
dataTemplate.VisualTree = frameworkElementFactory;
gridViewColumn.CellTemplate = dataTemplate;
Binding binding = new Binding(assignment.Id.ToString() + key);
binding.Converter = converter;
// *** this does not work ***
frameworkElementFactory.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Right);
frameworkElementFactory.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Right);
frameworkElementFactory.SetValue(TextBlock.ForegroundProperty, new SolidColorBrush(Color.FromRgb(100, 100, 100)));
frameworkElementFactory.SetBinding(TextBlock.TextProperty, binding);
// add column
gridView.Columns.Add(gridViewColumn);
}
If you want to center the content in a GridView inside a ListView, you can do it by creating an item container style for ListViewItem and set the HorizontalContentAlignment to Center.
var itemContainerStyle = new Style(typeof(ListViewItem));
var horizontalContentAlignmentSetter = new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Center);
itemContainerStyle.Setters.Add(horizontalContentAlignmentSetter);
listView.ItemContainerStyle = itemContainerStyle;
Here, listView is your list view instance. The alignment will apply to all columns. If you need to align columns individually, set the HorizontalContentAlignment in the item container template to Stretch.
var itemContainerStyle = new Style(typeof(ListViewItem));
var horizontalContentAlignmentSetter = new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Stretch);
itemContainerStyle.Setters.Add(horizontalContentAlignmentSetter);
listView.ItemContainerStyle = itemContainerStyle;
Then set the HorizontalAlignment of the controls inside the CellTemplate to what you need.
private void ListViewHelper(GridView gridView, ListView listView, MatrixId assignment, string key, IValueConverter converter)
{
// ...your code.
// Set the alignment to "Left", "Center", "Right" or "Stretch"
frameworkElementFactory.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Right);
// ...your code.
}
I have a question - I was coding happily a quick little feature to an app, which was a simple comparison output window.
Basically, user clicks a button and I generate a window with a datagrid of two columns of data.
It's all great and a five minutes code living inside one method with no unnecessary reference to anything else. The only problem I encountered was when I wanted to add a TopMost checkbox to this window.
How do I bind the IsChecked property of the box to the TopMost property of the window?
var checkbox = new CheckBox();
checkbox.Name = "cb";
checkbox.Content = "Top most";
var grid = new DataGrid();
grid.ItemsSource = wcList;
grid.Margin = new Thickness(5);
var panel = new StackPanel();
panel.Children.Add(checkbox);
panel.Children.Add(grid);
var win = new Window();
//Binding b = new Binding("cb");
//b.Mode = BindingMode.TwoWay;
//b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
//win.SetBinding(Window.TopmostProperty, b);
win.Title = "WordCount comparison";
win.Content = panel;
win.SizeToContent = SizeToContent.WidthAndHeight;
win.Icon = this.Icon;
win.Show();
This was supposed to be a 5-minutes one-off method, which is why I don't want to go as far as adding any xaml or properties into the code.
Cheers
Bartek
The other way around as you tried (in the commented code):
checkbox.SetBinding(CheckBox.IsCheckedProperty, new Binding("Topmost") { Source = win });
just after you instantiated your win variable.
I'm making a program for window phone using silverlight.
I have a small problem and it is about creating a combo box.
I can create it using xaml, but I am in a situation where I should declare it using c# code.
The problem is after creating a new instance of the combo box and adding the items to it, the combo box doesn't appear!!
The code:
TextBlock tb = new TextBlock();
tb.Text = "Select your arrival status";
tb.Margin = new Thickness(5.0);
tb.FontSize = 20;
tb.Foreground = new SolidColorBrush(Colors.White);
ComboBox cb = new ComboBox();
ObservableCollection<string> testList = new ObservableCollection<string>();
testList.Add("Hi");
testList.Add("Hi1");
testList.Add("Hi2");
cb.DataContext = testList;
cb.Height = 50;
cb.Width = 200;
cb.Foreground = new SolidColorBrush(Colors.White);
panel.Children.Add(tb);
panel.Children.Add(cb);
As you can see from the code, I have declared a TextBlock and a Combobox objects. The TextBox object appears whereas the the Combobox doesn't.
Any help will be appreciated.
You need to assign it a position. Your combo box is most likely under your text box. Either create the two of them using the designer and xaml, or be sure to assign x,y coordinates to them. Use the Margin property as well as HorizontalAlignment and VerticalAlignment.
I am new at C# & XAML development. I created a metro app with several textboxes. These textboxes are loaded in XAML data through a StackPanel in C# code, it has to be hardcoded. The problem is, I have no clue how I can add some empty spaces between every single textbox. Has anyone an idea?
The Code :
private void AddLastestCreatedField()
{
// Load the last created Field From DB
DBFunction.FieldTypes latestField;
DBFunction.Class1 myDBClass = new DBFunction.Class1();
latestField = myDBClass.GetLastestField();
// add new textbox and put it on the screen
var dragTranslation = new TranslateTransform();
//Generate the TextBox
TextBox fieldTextBox = new TextBox();
fieldTextBox.Name = "fieldTextBox_" + latestField.ID.ToString();
fieldTextBox.FontSize = 15;
fieldTextBox.Background.Opacity = 0.8;
ToolTip toolTip = new ToolTip();
toolTip.Content = latestField.Description;
ToolTipService.SetToolTip(fieldTextBox, toolTip);
fieldTextBox.IsReadOnly = true;
// Add Drag and Drop Handler for TextBox
fieldTextBox.ManipulationMode = ManipulationModes.All;
fieldTextBox.ManipulationDelta += fieldTextBox_ManipulationDelta;
fieldTextBox.ManipulationCompleted += fieldTextBox_ManipulationCompleted;
fieldTextBox.RenderTransform = dragTranslation;
dragTranslationDict.Add(fieldTextBox.Name, dragTranslation);
fieldTextBox.RenderTransform = dragTranslation;
// Add TextBox to a List to control later
TxtBoxList.Add(fieldTextBox);
// Generate TextBlock for each TextBlock
TextBlock fieldTextBlock = new TextBlock();
// fieldTextBlock.Name = "fieldTextBlock_" + cnt.ToString();
fieldTextBlock.TextAlignment = TextAlignment.Right;
fieldTextBlock.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Right;
fieldTextBlock.Name = "fieldTextBlock_" + latestField.ID.ToString();
fieldTextBlock.Text = latestField.Name;
fieldTextBlock.FontSize = 15;
fieldTextBlock.Height = 33;
// Add Drag and Drop Handler for TextBlock
var dragTranslation2 = new TranslateTransform();
fieldTextBlock.RenderTransform = dragTranslation2;
dragTranslationDict2.Add(fieldTextBlock.Name, dragTranslation2);
// Add TextBlock to a list to control later
TxtBlockList.Add(fieldTextBlock);
TextBoxStack.Children.Add(fieldTextBox);
TextBlockStack.Children.Add(fieldTextBlock);
}
I'll skip the usual "What have you tried?" question and say you probably can get what you need by setting the Margin property on the TextBox - the Margin property will add "space" around the control size as a sort of padding (not to be confused with the Padding property, which will add space inside the control extents)
I don't know what you are really up to, but either use the Margin-property of the textbox. It defines, how much space there will be around the control,
See MSDN for more information.
I have been trying to create a ContentTemplate using the lovely Frameworkelementfactory.
The code works except I can't set the content of the Button. I have tried many things but I always end up with a Button with Content= Button.
Here is the code which generates the contenttemplate. For your further info, I am using this in a Tabcontrol Header Itemtemplate...
Cheers.
ControlTemplate ct = new ControlTemplate(typeof(TabItem));
FrameworkElementFactory spouter = new FrameworkElementFactory(typeof (DockPanel));
FrameworkElementFactory text = new FrameworkElementFactory(typeof(TextBlock));
text.SetValue(TextBlock.TextProperty, Name);
spouter.AppendChild(text);
FrameworkElementFactory mButtonPrev = new FrameworkElementFactory(typeof(Button));
mButtonPrev.SetValue(System.Windows.Controls.Button.ContentProperty, "x");
mButtonPrev.AddHandler(System.Windows.Controls.Button.ClickEvent, new RoutedEventHandler(CloseTab));
spouter.AppendChild(mButtonPrev);
ct.VisualTree = spouter;
return ct;
ControlTemplate ct = new ControlTemplate(typeof(TabItem));
Shouldn't you be creating a DataTemplate here instead?
(Everything else looks fine to me, also FEF is deprecated, read the docs)
For those of use still using FEF, I was able to set the content of my button with the actual string. I see Name as where "button" is coming from in your example. In my example, Name pulls up the class name that I'm binding to my datagrid.
var buttonTemplate = new FrameworkElementFactory(typeof(Button));
var text = new FrameworkElementFactory(typeof(TextBlock));
text.SetValue(TextBlock.TextProperty, "Save");
buttonTemplate.AppendChild(text);
buttonTemplate.AddHandler(
System.Windows.Controls.Primitives.ButtonBase.ClickEvent,
new RoutedEventHandler((o, e) => MessageBox.Show("hi"))
);
AccountDatagrid.Columns.Add(new DataGridTemplateColumn()
{
Header = "Save",
CellTemplate = new DataTemplate() { VisualTree = buttonTemplate }
});
AccountDatagrid.ItemsSource = AccoutDescCodeTime.GetBaseAccounts();