How Can I Convert Xaml Code To C# (Setter Property in WPF) - c#

I have A problem regarding Converting Xaml to C# , I m using Auto complete Box Tab order is not working Properly On that Means First we move all the control and at last I goes on Auto complete Box i m solving this through the xaml code
<ToolKit:AutoCompleteBox.TextBoxStyle>
<Style TargetType="TextBox">
<Setter Property="TabIndex"
Value="{Binding ElementName=txtFirstName, Path=TabIndex}"/>
</Style>
</ToolKit:AutoCompleteBox.TextBoxStyle>
Now on Another i m using All Control Dynamic so no Xaml there For Auto complete My All Works Is to be Complete But i m Facing Same Tab order problem How Can I convert Above Xaml Code From C#
ctrl = new AutoCompleteBox { FontSize = 14, MaxDropDownHeight = 90 };
//Here We need to Implement That Style
ctrl.TabIndex = c.TabOrder;
ctrl.MaxWidth = 200;
if (c.SpName != null && c.DisplayMember != null)
{
DataTable dt = sqlHelper.ExecuteSelectProcedure(c.SpName);
var cmb = ctrl as AutoCompleteBox;
cmb.ItemsSource = dt.AsEnumerable().Select(r => r.Field<string>(c.DisplayMember)).ToList();
}
Please Help Me out Thanks And Regards
Shashank Tyagi

there is an application which you can do that, which is XamlT.
On WPF/SL apps, you can use XAML or C#/VB.NET code on some aspects (for example, to create an storyboard or set the image source).
Best regards

var style = new Style(typeof(TextBox));
var binding = new Binding("TabIndex") { ElementName = "txtFirstName" };
var setter = new Setter(TextBox.TabIndexProperty, binding);
style.Setters.Add(setter);
ctrl.TextBoxStyle = style;

else if (c.Type == typeof(AutoCompleteBox))
{
//var style = new Style(typeof(TextBox));
ctrl = new AutoCompleteBox { FontSize = 14, MaxDropDownHeight = 90, Name = c.ControlID };
ctrl.TabIndex = c.TabOrder;
ctrl.MaxWidth = 200;
var style = new Style(typeof(TextBox));
var binding = new Binding("TabIndex") { ElementName = c.ControlID };
var setter = new Setter(TextBox.TabIndexProperty, binding);
style.Setters.Add(setter);
(ctrl as AutoCompleteBox).TextBoxStyle = style;
if (c.SpName != null && c.DisplayMember != null)
{
DataTable dt = sqlHelper.ExecuteSelectProcedure(c.SpName);
var cmb = ctrl as AutoCompleteBox;
cmb.ItemsSource = dt.AsEnumerable().Select(r => r.Field<string>(c.DisplayMember)).ToList();
}
}
This Code Perfectly works

Related

UWP style setter value binding not working code behind

I have a dinamic datagrid with dinamic number of columns.
Add one column code in my cycle:
CValueConverter valueConverter = new CValueConverter()
{
Field = fieldDg
};
Style textStyle = new Style(typeof(TextBlock));
textStyle.Setters.Add(new Setter(TextBlock.TextTrimmingProperty, TextTrimming.CharacterEllipsis));
textStyle.Setters.Add(
new Setter(
ToolTipService.ToolTipProperty,
new Binding
{
Path = new PropertyPath("[" + cmnIndex.ToString() + "]"),
Converter = valueConverter
}));
this.FormListDg.Columns.Add(new DataGridTextColumn()
{
Header = fieldDg.Name,
HeaderStyle = this.GetHeaderStyle(fieldDg.Color),
CellStyle = this.GetCellStyle(fieldDg.Color),
CanUserSort = true,
MaxWidth = 300,
Binding = new Binding
{
Path = new PropertyPath("[" + cmnIndex.ToString() + "]"),
Converter = valueConverter
},
ElementStyle = textStyle
});
cmnIndex++;
The result of this datagrid cell tooltip is:
When I change the style setter value to constant, everything is works fine:
textStyle.Setters.Add(
new Setter(
ToolTipService.ToolTipProperty,
"VALAMI"));
How can I use binding in style setter value?
The Value of the Setter should to be set to a (data-bound) Tooltip and not Binding:
ToolTip tt = new ToolTip();
tt.SetBinding(ContentControl.ContentProperty, new Binding
{
Path = new PropertyPath("[" + cmnIndex.ToString() + "]"),
Converter = valueConverter
});
textStyle.Setters.Add(
new Setter(
ToolTipService.ToolTipProperty,
tt));

How do I Inherit a WPF DataGrid Cell Style when programmatically adding a DataTrigger?

I'm writing a WPF application which makes use of the DataGrid control. I'm using the MaterialDesign theme to style the application and this gives a nice look and feel.
However for complex reasons I wont go into here I'm required to add the columns into the dataGrid programmatically. For some of the columns I'm also styling the columns to highlight pass / fail in red. When I do this I loose 'some of the styling' provided by material design for that columns. Namely the Horizontal and Vertical alignment.
The code to the above is as follows:
// Define Setter
Setter setterResultFail = new Setter();
setterResultFail.Property = DataGridCell.BackgroundProperty;
setterResultFail.Value = Brushes.Red;
// Create a column for the Site.
var currentColumn = new DataGridTextColumn();
currentColumn.Header = "Device #";
currentColumn.Binding = new Binding("Device");
ResultsDataGrid.Columns.Add(currentColumn);
// Create a column for the Site.
currentColumn = new DataGridTextColumn();
currentColumn.Header = "Site";
currentColumn.Binding = new Binding("Site");
ResultsDataGrid.Columns.Add(currentColumn);
// Create a column for the Pass Fail.
currentColumn = new DataGridTextColumn();
currentColumn.Header = "Pass Fail";
currentColumn.Binding = new Binding("PassFail") { Converter = new BooleanToPassFailConverter() };
// Create cellstyle to make the cell 'red' when the PassFail value is False. ( this is done via a data trigger )
cellStyle = new Style(typeof(DataGridCell));
// Define First DataTrigger that sets a CELL red if the value is a fail.
dataTrigger = new DataTrigger();
dataTrigger.Value = "False";
dataTrigger.Binding = new Binding("PassFail");
dataTrigger.Setters.Add(setterResultFail);
// Add the data-triggers to the cell style.
cellStyle.Triggers.Clear();
cellStyle.Triggers.Add(dataTrigger);
// Apply the newly created cell style.
currentColumn.CellStyle = cellStyle;
ResultsDataGrid.Columns.Add(currentColumn);
Clearly the new cellStyle is used instead of the MaterialDesign style. I've tried setting the values for vertical / horizontal manually but I can't get it to look correct:
Setter setterTextContentHorizonalAlignment = new Setter();
setterTextContentHorizonalAlignment.Property = DataGridCell.HorizontalContentAlignmentProperty;
setterTextContentHorizonalAlignment.Value = HorizontalAlignment.Center;
Setter setterTextContentVerticalAlignment = new Setter();
setterTextContentVerticalAlignment.Property = DataGridCell.VerticalContentAlignmentProperty;
setterTextContentVerticalAlignment.Value = VerticalAlignment.Center;
Setter setterTextHorizontalAlignment = new Setter();
setterTextHorizontalAlignment.Property = DataGridCell.HorizontalAlignmentProperty;
setterTextHorizontalAlignment.Value = HorizontalAlignment.Center;
Setter setterTextVerticalAlignment = new Setter();
setterTextVerticalAlignment.Property = DataGridCell.VerticalAlignmentProperty;
setterTextVerticalAlignment.Value = VerticalAlignment.Center;
cellStyle.Setters.Add(setterTextContentHorizonalAlignment);
cellStyle.Setters.Add(setterTextContentVerticalAlignment);
cellStyle.Setters.Add(setterTextHorizontalAlignment);
cellStyle.Setters.Add(setterTextVerticalAlignment);
Is there a way I can add to the style rather than replace it...similar to the BasedOn approch in XAML?
After much wasting of time on this question I came across Danny Beckett's similar question and King King's answer. By using his answer and applying it to the specific cell I was having trouble with it fixed the issue:King King's answer
// Create a column for the Pass Fail.
currentColumn = new DataGridTextColumn();
currentColumn.Header = "Pass Fail";
currentColumn.Binding = new Binding("PassFail") { Converter = new BooleanToPassFailConverter() };
// Create cellstyle to make the cell 'red' when the PassFail value is False. ( this is done via a data trigger )
cellStyle = new Style(typeof(DataGridCell));
// Define First DataTrigger that sets a CELL red if the value is a fail.
dataTrigger = new DataTrigger();
dataTrigger.Value = "False";
dataTrigger.Binding = new Binding("PassFail");
dataTrigger.Setters.Add(setterResultFail);
// Add the data-triggers to the cell style.
cellStyle.Triggers.Clear();
cellStyle.Triggers.Add(dataTrigger);
//root visual of the ControlTemplate for DataGridCell is a Border
var border = new FrameworkElementFactory(typeof(Border));
border.SetBinding(Border.BorderBrushProperty, new Binding("BorderBrush")
{
RelativeSource = RelativeSource.TemplatedParent
});
border.SetBinding(Border.BackgroundProperty, new Binding("Background") { RelativeSource = RelativeSource.TemplatedParent });
border.SetBinding(Border.BorderThicknessProperty, new Binding("BorderThickness") { RelativeSource = RelativeSource.TemplatedParent });
border.SetValue(SnapsToDevicePixelsProperty, true);
//the only child visual of the border is the ContentPresenter
var contentPresenter = new FrameworkElementFactory(typeof(ContentPresenter));
contentPresenter.SetBinding(SnapsToDevicePixelsProperty, new Binding("SnapsToDevicePixelsProperty") { RelativeSource = RelativeSource.TemplatedParent });
contentPresenter.SetBinding(VerticalAlignmentProperty, new Binding("VerticalContentAlignment") { RelativeSource = RelativeSource.TemplatedParent });
contentPresenter.SetBinding(HorizontalAlignmentProperty, new Binding("HorizontalContentAlignment") { RelativeSource = RelativeSource.TemplatedParent });
//add the child visual to the root visual
border.AppendChild(contentPresenter);
//here is the instance of ControlTemplate for DataGridCell
var template = new ControlTemplate(typeof(DataGridCell));
template.VisualTree = border;
//define the style
cellStyle.Setters.Add(new Setter(TemplateProperty, template));
cellStyle.Setters.Add(new Setter(VerticalContentAlignmentProperty, VerticalAlignment.Center));
cellStyle.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
// Apply the newly created cell style.
currentColumn.CellStyle = cellStyle;

getting value from elements created dynamically

im working on a project(UWP C sharp) from college..
i need to build library program that manege books and magazines
i have a problem with the edit item page...
iv created method that create elements (text box, datepicker , etc..) dynamically by the type of the item that selected (if the user select book, he'll get the elements for book same for magazines..)
the problem is when im trying to write the event button that take the values from all those elements i cant reach them... cuz they in a method..
(like book.title = textbox.text;)
sorry for my English and Ty for the help:)
private void CreateBtnsByTheTypeOfTheItem(AbstractItem item)
{
TextBox editTitleTB = new TextBox();
editTitleTB.Text = LibManager.Instance.CurrentItem.Title;
Grid.SetRow(editTitleTB, 0);
editPageGrid.Children.Add(editTitleTB);
CheckBox editIsAvaibleCB = new CheckBox();
editIsAvaibleCB.Content = "Is Avaible";
editIsAvaibleCB.IsChecked = item.isAvaible;
Grid.SetRow(editIsAvaibleCB, 1);
editPageGrid.Children.Add(editIsAvaibleCB);
DatePicker editDatePicler = new DatePicker();
editDatePicler.Date = item.PublishDate;
Grid.SetRow(editDatePicler, 3);
editPageGrid.Children.Add(editDatePicler);
if (item is Book)
{
Book itemAsBook = item as Book;
TextBox editAuthor = new TextBox();
editAuthor.Text = itemAsBook.Author;
Grid.SetRow(editAuthor, 2);
editPageGrid.Children.Add(editAuthor);
var _enumval = Enum.GetValues(typeof(BookCategory)).Cast<BookCategory>();
ComboBox editCategpryCB = new ComboBox();
editCategpryCB.ItemsSource = _enumval.ToList();
editCategpryCB.SelectedItem = itemAsBook.Category;
Grid.SetRow(editCategpryCB, 4);
editPageGrid.Children.Add(editCategpryCB);
}
else
{
Magazine itemAsMagazine = item as Magazine;
TextBox editEditors = new TextBox();
editEditors.Text = itemAsMagazine.Editors;
Grid.SetRow(editEditors, 2);
editPageGrid.Children.Add(editEditors);
var _enumval = Enum.GetValues(typeof(MagazineCategory)).Cast<MagazineCategory>();
ComboBox editMagazineCategory = new ComboBox();
editMagazineCategory.ItemsSource = _enumval.ToList();
editMagazineCategory.SelectedItem = itemAsMagazine.Category;
Grid.SetRow(editMagazineCategory, 4);
editPageGrid.Children.Add(editMagazineCategory);
}
If you have named each of the dynamically created field you can access them by using the FindName method.
TextBox editTitleTB = new TextBox();
editTitleTB.Name = "TheHobbitTB";
editTitleTB.Text = LibManager.Instance.CurrentItem.Title;
TextBox theHobbitTB = (TextBox)this.FindName("TheHobbitTB");
Then you could essentially edit what ever you want about this specific textbox.

Bindings on Datagrids in code Behind

I'm working on a cookbook for myself, written in WPF/C#.
Additionally I'm new to Data Bindings.
My Problem is, I want to generate a Datagrid in a TabItem on runtime in code behind, including Bindings. I can't set a Datagrid at XAML because I want to create all TabItems dynamically.
Following Code so far:
XAML:
<UniformGrid Columns="2" Rows="1">
<TabControl Name="TabControl" TabStripPlacement="Left"/>
<TabItem Header= "first dish" Name = "firstdish"/>
</UniformGrid>
XAML.cs for generation:
//New Grid
var Grid = new DataGrid();
//Start Test list creation with three items
var TestList = new List<Receipt>();
//Set binding
Grid.ItemsSource = TestList;
var Rec = new Receipt();
Rec.Creator = "DaJohn1";
Rec.ID = 1;
Rec.Title = "TestReceipt1";
var Rec2 = new Receipt();
Rec2.Creator = "DaJohn2";
Rec2.ID = 2;
Rec2.Title = "TestReceipt2";
var Rec3 = new Receipt();
Rec3.Creator = "DaJohn3";
Rec3.ID = 3;
Rec3.Title = "TestReceipt3";
TestList.Add(Rec);
TestList.Add(Rec2);
TestList.Add(Rec3);
//End Test list creation
//Add Column
var SingleColumn = new DataGridTextColumn();
Grid.Columns.Add(SingleColumn);
SingleColumn.Binding = new Binding("Creator");
SingleColumn.Header = "Creator";
//Add Column
var SingleColumn2 = new DataGridTextColumn();
Grid.Columns.Add(SingleColumn2);
SingleColumn2.Binding = new Binding("Title");
SingleColumn2.Header = "Title";
//Set tabitem content to datagrid
firstdish.Content = Grid;
All I'm getting is an datagrid with four rows (looks like the count of Items is right), which are all empty, no data to be seen.
I'm staring at this since last Weeks Monday and can't find an answer anywhere.
Thanks for any ideas and solutions.
try changing
var TestList = new List<Receipt>();
to
var TestList = new ObservableCollection<Receipt>();
as it automatically notifies UI about changes.
I had a similar problem with items not rendering so this may be it.
I've taken your code and checked some of the things you do: The main error is that in your xaml code you created the Tab Control and then Put the TabItem outside it, Tabitem must be inside the control for it to work correctly. so First error is:
<TabControl Name="TabControl" TabStripPlacement="Left">
<TabItem Header="First dish" Name = "firstdish" />
</TbControl>
Other things you need to do before going on in my opinion are:
Assign your window or other UI element itself as datacontext
Verify that your Receipt class implements the INotifyPropertyChanged event that has to be raised by all its properties, or implement your properties as DependencyProperties (even if the latter is not necessary)
Transform your datasource TestList in an ObservableCollection
Create TestList as a class property not a local variable so that it is into the datacontext
I've made a small sample using the above indication and your code to let you see better how that works. You can download the zip here:
TestClassDataGrid.zip
Below code should work for you,
XAML:
<TabControl Name="TabControl" TabStripPlacement="Left">
<TabItem Header= "first dish" Name = "firstdish"/>
</TabControl>
.cs file
public Window()
{
InitializeComponent();
var Grid = new DataGrid();
//Start Test list creation with three items
var TestList = new List<Receipt>();
//Set binding
Grid.ItemsSource = TestList;
var Rec = new Receipt();
Rec.Creator = "DaJohn1";
Rec.ID = 1;
Rec.Title = "TestReceipt1";
var Rec2 = new Receipt();
Rec2.Creator = "DaJohn2";
Rec2.ID = 2;
Rec2.Title = "TestReceipt2";
var Rec3 = new Receipt();
Rec3.Creator = "DaJohn3";
Rec3.ID = 3;
Rec3.Title = "TestReceipt3";
TestList.Add(Rec);
TestList.Add(Rec2);
TestList.Add(Rec3);
//End Test list creation
//Add Column
var SingleColumn = new DataGridTextColumn();
Grid.Columns.Add(SingleColumn);
SingleColumn.Binding = new Binding("Creator");
SingleColumn.Header = "Creator";
//Add Column
var SingleColumn2 = new DataGridTextColumn();
Grid.Columns.Add(SingleColumn2);
SingleColumn2.Binding = new Binding("Title");
SingleColumn2.Header = "Title";
//Set tabitem content to datagrid
Grid.AutoGenerateColumns = false;
firstdish.Content = Grid;
}

Persist Dynamically Added Controls w/ DataTriggers WPF

I am currently working on a WPF project that uses Caliburn.Micro and have hit a snag I was hoping you could help with. I have a form that allows the user to add new fields to a separate form with the intention that these new fields will persist. I am able to create these controls dynamically with the following code:
Grid tmpOuterGrid = new Grid();
RowDefinition rowDefinition1 = new RowDefinition();
RowDefinition rowDefinition2 = new RowDefinition();
rowDefinition1.Height = new GridLength(45, GridUnitType.Star);
rowDefinition2.Height = new GridLength(55, GridUnitType.Star);
tmpOuterGrid.RowDefinitions.Add(rowDefinition1);
tmpOuterGrid.RowDefinitions.Add(rowDefinition2);
tmpOuterGrid.Margin = new Thickness(0,0,0,10);
Grid tmpInnerGrid = new Grid();
Grid.SetRow(tmpInnerGrid, 0);
tmpInnerGrid.Margin = new Thickness(10,0,0,5);
tmpInnerGrid.Opacity = 0;
DataTrigger d = new DataTrigger();
Binding b = new Binding("DisplayFieldName");
b.Source = _fieldNames[primaryNameBase + "FieldTextBox"];
d.Binding = b;
d.Value = true;
Storyboard sbEnter = new Storyboard();
DoubleAnimation opAnimShow = new DoubleAnimation(1,new Duration(new TimeSpan(0,0,0,1)));
Storyboard.SetTargetProperty(sbEnter, new PropertyPath(UIElement.OpacityProperty));
sbEnter.Children.Add(opAnimShow);
Storyboard sbExit = new Storyboard();
DoubleAnimation opAnimHide = new DoubleAnimation(0, new Duration(new TimeSpan(0, 0, 0, 1)));
Storyboard.SetTargetProperty(sbExit, new PropertyPath(UIElement.OpacityProperty));
sbExit.Children.Add(opAnimHide);
BeginStoryboard bsEnter = new BeginStoryboard { Storyboard = sbEnter, Name = "beginStoryboardEnter" };
BeginStoryboard bsExit = new BeginStoryboard { Storyboard = sbExit, Name = "beginStoryboardExit" };
d.EnterActions.Add(bsEnter);
d.ExitActions.Add(bsExit);
Style st = new Style(typeof(Grid));
st.Triggers.Add(d);
tmpInnerGrid.Style = st;
TextBlock tb = new TextBlock();
tb.Name = primaryNameBase + "FieldHeaderText";
tb.Foreground = new SolidColorBrush(Color.FromArgb(136,255,255,255));
tb.FontSize = 14;
tb.Style = (Style) App.Current.Resources["NexaLightTextBlock"];
tb.HorizontalAlignment = HorizontalAlignment.Center;
tb.Text = fieldTextBox.DisplayText;
Border underline = new Border();
underline.BorderThickness = new Thickness(0, 0, 0, 1);
underline.BorderBrush = new SolidColorBrush(Color.FromArgb(136,49,250,250));
underline.VerticalAlignment = VerticalAlignment.Bottom;
underline.HorizontalAlignment = HorizontalAlignment.Center;
Binding binding = new Binding
{
Source = tb,
Path = new PropertyPath("ActualWidth"),
};
underline.SetBinding(FrameworkElement.WidthProperty, binding);
tmpInnerGrid.Children.Add(tb);
tmpInnerGrid.Children.Add(underline);
LowBorderTextBox lbtb = new LowBorderTextBox();
lbtb.Name = primaryNameBase + "FieldTextBox";
Grid.SetRow(lbtb, 1);
lbtb.Width = 140;
lbtb.Margin = new Thickness(10,0,0,0);
lbtb.FontColor = new SolidColorBrush(Colors.White);
lbtb.DisplayFontSize = 22;
lbtb.Style = (Style) App.Current.Resources["NexaLightCustomTextBox"];
lbtb.DisplayText = fieldTextBox.DisplayText;
lbtb.LostFocus += FieldLostFocus;
tmpOuterGrid.Children.Add(tmpInnerGrid);
tmpOuterGrid.Children.Add(lbtb);
wrapPanel.Children.Add(tmpOuterGrid);
I would then like these new controls to be persisted through application shutdowns. The approach I was thinking of taking was serializing the object into xaml and storing that in a file, and then reading this file and deserializing it to obtain the control object again, which would be added to my surrounding WrapPanel. This is all fine and dandy except for one detail. The controls that are created have a style with a datatrigger that is bound to a property of a NoteField object, there being one NoteField object for each of these types of control. I was planning on serializing the NoteField objects as well, so that I could just pull them back and hope that the binding would still be intact, but they implement the PropertyChangedBase interface of the Caliburn.Micro framework, and the NotifyOfPropertyChange() method is not marked as serializable. Here is the NoteField class:
[Serializable]
class NoteField : PropertyChangedBase
{
private string _controlName;
private bool _displayFieldName;
public bool DisplayFieldName
{
get { return _displayFieldName; }
set
{
_displayFieldName = value;
NotifyOfPropertyChange(() => DisplayFieldName);
}
}
private string _fieldName;
public string FieldName
{
get { return _fieldName; }
set
{
_fieldName = value;
NotifyOfPropertyChange(() => FieldName);
}
}
public NoteField(string controlName, string displayText)
{
DisplayFieldName = false;
_controlName = controlName;
FieldName = displayText;
}
public string GetControlName()
{
return _controlName;
}
public void SetControlName(string name)
{
_controlName = name;
}
}
I am not attached to using this class, but it was the only way I could think of having dynamically generated properties to bind to from the xaml. So, I guess my question is: is there a way that I can dynamically create controls that have bindings in them that can persist through application shutdowns? Am I on the right track, or should I do something else all together? Any help would be greatly appreciated. Thank you so much for your time.

Categories

Resources