I have done below code in XAML. But, I dont wanna create Text Binding in XAML. Is there anyway to create the same method in C# programmatically ?
XAML CODE:
<TextBox Name="contentBox" Text="{Binding Content, Mode=TwoWay}" AcceptsReturn="True" />
TextBox tb = new TextBox();
tb.Name = "contentBox";
tb.AcceptsReturn = true;
Binding b = new Binding("Content");
b.Mode = BindingMode.TwoWay;
b.Source = this; // set you DataContext here
tb.SetBinding(TextBlock.TextProperty, b);
It will look something like this:
var tb = new TextBox();
tb.SetValue(NameProperty, "contentBox");
tb.AcceptsReturn = true;
var b = new Binding("Content");
b.Mode = BindingMode.TwoWay;
b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(tb, TextBox.TextProperty, b);
You will still need to implement an INotifyPropertyChanged class for your DataContext, and manually insert the code-created TextBox into your visual tree somewhere.
Binding binding = new Binding();
binding.Mode = BindingMode.TwoWay;
binding.Path = new PropertyPath("Content"); //Name of the property in Datacontext
BindingOperations.SetBinding(contentBox,TextBox.TextProperty , binding);
Related
I'm trying to hide a dynamic combobox what is set from FrameworkElementFactory.
If i try Combobox as parameter then i get the error 'ComboBox' is a type, which is not valid in the given context and if i try fElement as parameter then it gives the error "cannot convert from 'System.Windows.FrameworkElementFactory' to 'System.Windows.DependencyObject'" I need the solution in C# not in xaml or ASP.net.
FrameworkElementFactory fElement = new FrameworkElementFactory(typeof(ComboBox));
fElement.SetValue(ComboBox.WidthProperty, 125D);
fElement.SetValue(ComboBox.ItemsSourceProperty, choices);
fElement.SetValue(ComboBox.DisplayMemberPathProperty, "Value");
fElement.SetValue(ComboBox.SelectedValuePathProperty, "Value");
fElement.SetValue(ComboBox.NameProperty, "CONAAM" + rowOnderdeel.OnderdeelID);
//fElement.SetValue(ComboBox.NameProperty, Onderdeelnaam);
fElement.AddHandler(Selector.SelectionChangedEvent, new SelectionChangedEventHandler(cbCursistOnderdeelResultaat));
fElement.SetBinding(ComboBox.TextProperty, bind);
Interaction.GetBehaviors(ComboBox).Add(new HideComboxBehavior());
Solutions was to use System.Windows.Style and use setter to trigger the visibility of the combobox.
FrameworkElementFactory fElement = new FrameworkElementFactory(typeof(ComboBox));
fElement.SetValue(ComboBox.WidthProperty, 125D);
fElement.SetValue(ComboBox.ItemsSourceProperty, Resultaten);
fElement.SetValue(ComboBox.DisplayMemberPathProperty, "Value");
fElement.SetValue(ComboBox.SelectedValuePathProperty, "Key");
fElement.SetValue(ComboBox.SelectedValueProperty, new Binding(column.ColumnName));
Style cbStyle = new Style(typeof(ComboBox));
Setter cbSetter = new Setter(ComboBox.VisibilityProperty, Visibility.Visible);
cbStyle.Setters.Add(cbSetter);
DataTrigger cbDataTrigger = new DataTrigger();
Binding cbBinding = new Binding(column.ColumnName);
cbDataTrigger.Value = 0;
Setter cbDataSetter = new Setter(ComboBox.VisibilityProperty, Visibility.Hidden);
cbDataTrigger.Setters.Add(cbDataSetter);
cbDataTrigger.Binding = cbBinding;
cbStyle.Triggers.Add(cbDataTrigger);
fElement.SetValue(ComboBox.StyleProperty, cbStyle);
DataTemplate dataTemplate = new DataTemplate();
dataTemplate.VisualTree = fElement;
gvc.CellTemplate = dataTemplate;
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;
}
I got a problem with my datagrid. When i click on an element my row become selected and my selected style apply.
but when i scroll, if the element is there again (not duplicate value, item reference are the same), it become in blue, like selected default style.
Having the same item highlight is not a problem, but i would like to put my selected style (the violet dot in row header). In debug, the rows in blue are not selected (and if they were my style would apply). What is the property for being highlight for the duplicate object.
Edit
Binding oBindRowSelected = new Binding();
Binding oBindCellSelected = new Binding();
Binding oBindBackGround = new Binding();
Binding oBindBorderBrush = new Binding();
Binding oBindForeGround = new Binding();
oBindRowSelected.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridRow), 1);
oBindCellSelected.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridCell), 1);
oBindRowSelected.Path = new PropertyPath(DataGridRow.IsSelectedProperty);
oBindCellSelected.Path = new PropertyPath(DataGridCell.IsSelectedProperty);
oBindBackGround.Path = new PropertyPath(DataGridRow.BackgroundProperty);
oBindBorderBrush.Path = new PropertyPath(DataGridRow.BorderBrushProperty);
oBindForeGround.Path = new PropertyPath(DataGridRow.ForegroundProperty);
DataTrigger oTriggerSelectedImageVisibility = new DataTrigger();
oTriggerSelectedImageVisibility.Binding = oBindRowSelected;
oTriggerSelectedImageVisibility.Value = true;
oTriggerSelectedImageVisibility.Setters.Add(new Setter(Border.VisibilityProperty, Visibility.Visible));
DataTrigger oTriggerSelectedCell = new DataTrigger();
oTriggerSelectedCell.Binding = oBindRowSelected;
oTriggerSelectedCell.Value = true;
oTriggerSelectedCell.Setters.Add(new Setter(DataGridCell.BackgroundProperty, oBindBackGround));
oTriggerSelectedCell.Setters.Add(new Setter(DataGridCell.BorderBrushProperty, oBindBorderBrush));
oTriggerSelectedCell.Setters.Add(new Setter(DataGridCell.ForegroundProperty, oBindForeGround));
Style oRowHeaderSelectorStyle = new Style(typeof(Border));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(7)));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.HeightProperty, 15.0));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.WidthProperty, 15.0));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.BackgroundProperty, Brushes.BlueViolet));
oRowHeaderSelectorStyle.Setters.Add(new Setter(Border.VisibilityProperty, Visibility.Hidden));
oRowHeaderSelectorStyle.Triggers.Add(oTriggerSelectedImageVisibility);
ControlTemplate oCtlTemplate = new ControlTemplate();
FrameworkElementFactory oBorder = new FrameworkElementFactory(typeof(Border));
oBorder.SetValue(Border.StyleProperty, oRowHeaderSelectorStyle);
oCtlTemplate.VisualTree = oBorder;
Style oRowHeaderStyle = new Style(typeof(DataGridRowHeader));
oRowHeaderStyle.Setters.Add(new Setter(DataGridRowHeader.WidthProperty, 25.0));
oRowHeaderStyle.Setters.Add(new Setter(DataGridRowHeader.TemplateProperty, oCtlTemplate));
Style oCellStyle = new Style(typeof(DataGridCell));
oCellStyle.Triggers.Add(oTriggerSelectedCell);
this.RowHeaderStyle = oRowHeaderStyle;
this.CellStyle = oCellStyle;
I am working in an extension, so my style is in C# code.
Why is this code-behind DataBinding not working, when I do the same thing in XAML it is working fine.
Binding frameBinding = new Binding();
frameBinding.Source = mainWindowViewModel.PageName;
frameBinding.Converter = this; // of type IValueConverter
frameBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
frameBinding.IsAsync = true;
frame.SetBinding(Frame.ContentProperty, frameBinding);
You have only set the Source of the Binding, but not its Path. The declaration should look like this, using the mainWindowViewModel instance as Source:
Binding frameBinding = new Binding();
frameBinding.Path = new PropertyPath("PageName"); // here
frameBinding.Source = mainWindowViewModel; // and here
frameBinding.Converter = this;
frameBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
frameBinding.IsAsync = true;
frame.SetBinding(Frame.ContentProperty, frameBinding);
or shorter:
Binding frameBinding = new Binding
{
Path = new PropertyPath("PageName"),
Source = mainWindowViewModel,
Converter = this,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
IsAsync = true
};
frame.SetBinding(Frame.ContentProperty, frameBinding);
In code i add columns to listview successfuly. But i want add binding to column than add to listview.
fist is working code in xaml.
<GridViewColumn x:Name="colName" Header="Name" Width="130">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Values, Converter={StaticResource LoadProfileConverter},ConverterParameter=active_total}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Code behind:
GridViewColumn column = new GridViewColumn();
column.Header = "Header";
column.Width = 130;
FrameworkElementFactory controlFactory = new FrameworkElementFactory(typeof(TextBlock));
var itemsBinding = new System.Windows.Data.Binding("Values")
{
Converter = new LoadProfileConverter(),
ConverterParameter = "active_total",
};
controlFactory.SetBinding(TextBox.TextProperty, itemsBinding);
DataTemplate template = new DataTemplate();
template.VisualTree = controlFactory;
column.CellTemplate = template;
LoadProfileGrid.Columns.Add(column);
var itemsbinding = new Binding("Values")
{
Converter = new LoadProfileConverter(),
ConverterParameter = key
};
controllerFactory.SetBinding(TextBox.TextProperty, itemsbinding);
Create a proper binding using the code above.
Loads of extra properties on the binding object that can assist you.
GridViewColumn column = new GridViewColumn();
column.Header = key;
column.Width = 130;
FrameworkElementFactory controlFactory = new FrameworkElementFactory(typeof(TextBlock));
var itemsBinding = new System.Windows.Data.Binding("Values")
{
Converter = new LoadProfileConverter(),
ConverterParameter = key
};
column.DisplayMemberBinding = itemsBinding;
LoadProfileGrid.Columns.Add(column);