WPF Code-behind DataBinding Not Working - c#

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);

Related

Interaction.GetBehaviors from FrameworkElementFactory type combobox

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;

binding a property to the colomn in RadGridView in code behind

I have a list of custom classes that I have bound them to the RadGridView through the below code:
this.ItemsSource = CorrelationCalibraationGridInput.ListOfCalibratableCorrelationClasses;
then I have created the columns manually. For one of the columns that is check box column, I need to enable disable the check box binding to a property of class and set its check state based on another property of the class.
I used the code below but the enablity does not bind to the IsNotCalibratedYet property. Can you explain why and how can I solve it?(note that the check state is correctly binded to the IsCalibratedUSed property of the class).
GridViewDataColumn IsCalibratedUSedColumn = new GridViewDataColumn()
{
UniqueName = "IsCalibratedUSedColumn",
Header = "Use calibrated",
DataMemberBinding = new Binding("IsCalibratedUSed"),
IsFilterable = false,
};
Binding enablityBinding = new Binding("IsNotCalibratedYet");
enablityBinding.Mode= BindingMode.OneWay;
enablityBinding.UpdateSourceTrigger= UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(IsCalibratedUSedColumn, GridViewDataColumn.IsEnabledProperty,enablityBinding );
this.Columns.Add(IsCalibratedUSedColumn);
You should set the IsReadOnlyBinding property of the GridViewDataColumn to your Binding:
GridViewDataColumn IsCalibratedUSedColumn = new GridViewDataColumn()
{
UniqueName = "IsCalibratedUSedColumn",
Header = "Use calibrated",
DataMemberBinding = new Binding("IsCalibratedUSed"),
IsFilterable = false,
};
Binding enablityBinding = new Binding("IsNotCalibratedYet");
enablityBinding.Mode = BindingMode.OneWay;
enablityBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
IsCalibratedUSedColumn.IsReadOnlyBinding = enablityBinding;
this.Columns.Add(IsCalibratedUSedColumn);
Depending on whether your source property returns true/false you may want to use an InvertedBooleanConverter:
Binding enablityBinding = new Binding("IsNotCalibratedYet");
enablityBinding.Mode = BindingMode.OneWay;
enablityBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
enablityBinding.Converter = new InvertedBooleanConverter();
You can do this using the following setting:
public MainWindow()
{
InitializeComponent();
lv.ItemsSource = new Item[3] { new Item() { IsNotCalibratedYet=true }, new Item() { IsNotCalibratedYet = false }, new Item() { IsNotCalibratedYet = true } };
gv.Columns.Add(new GridViewColumn()
{
DisplayMemberBinding = new Binding("IsNotCalibratedYet"),
});
}
in which:
public class Item
{
public bool IsNotCalibratedYet { get; set; }
}
and Xaml is
<ListView Name="lv" >
<ListView.View>
<GridView x:Name="gv" AllowsColumnReorder="true"
ColumnHeaderToolTip="Employee Information">
</GridView>
</ListView.View>
</ListView>

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.

The same object 2 time in datagrid

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.

how to create C# code for below XAML code?

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);

Categories

Resources