WPF Binding with a Border - wpf

I have a group of borders that make up a small map. Ideally I'd like to be able to bind the border's background property to a property in a custom list and when that property changes it changes the background.
The tricky thing is, I have to do this in code behind.

Use the FrameworkElement.SetBinding method:
myBorder.SetBinding(Border.BackgroundProperty, "CurrentBackground");
or, if you need sources and converters and things:
myBorder.SetBinding(Border.BackgroundProperty,
new Binding(somePath) {
Source = something,
Converter = new WonderConverter()
// etc.
});

Related

WPF Datagrid Button commandParameter in code behind

I'm trying to build a datagrid with columns and a button in code behind and I want to assign the command parameter of this button to the value of the "ID" column which is "TDENT_ID". Here's my code
this line is not working as you can see :
BtnDetail.SetBinding(System.Windows.Controls.Primitives.ButtonBase.CommandParameterProperty, new Binding() { Source = dtGrid, Path = "TDENT_ID" });
How can I write it?
FrameworkElementFactory:
"This class is a deprecated way to programmatically create templates, which are subclasses of FrameworkTemplate such as ControlTemplate or DataTemplate; not all of the template functionality is available when you create a template using this class. The recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Load method of the XamlReader class." Microsoft Docs
Your Bindingis wrong. It currently points to the DataGrid which does not have a property TDENT_ID.
This property is on your data item, which is the DataContext of the column's template.
Therefore, correct Binding would be:
// Set up a Binding that uses the current DataContext as Binding.Source
BtnDetail.SetBinding(ButtonBase.CommandParameterProperty, new Binding(nameof(myItemType.TDENT_ID)));
Microsoft Docs: Specifying the binding source
Try to learn XAML. It makes writing such UI related code much easier, which makes you more productive.

How to add borders to WPF ListView in code

I have created a ListView with a GridView in code.
ListView gridList = new ListView();
GridView gridListView = new GridView ();
gridList.View = gridListView;
Now, I define a GridViewColumn, set the header, width and bindingPath. All good and the data shows up.
GridViewColumn listColumn = new GridViewColumn();
listColumn.Header = "Some Header";
listColumn.Width = 100.0;
listColumn.DisplayMemeberBinding = new Binding("Name");
gridListView.Columns.Add(listColumn);
But there are no borders/gridlines shown on display of this ListView. How can I add borders through code?
Someone described my exact problem here but no good solution mentioned
http://social.msdn.microsoft.com/Forums/en-US/fa4fa8e0-81fe-487a-8763-590062d29c06/wpf-listview-gridview-row-border?forum=wpf
The logic in WPF programming is totally different from what you've done in winforms. Everything related to UI should always be set up using XAML (as much as possible). The WPF library itself has many parts desgined mainly for use in XAML although there is always an equivalent codebehind. However that's when using codebehind may be awkward and non-intuitive (as well as straight-forward).
I understand that you want something like the ListView Grid in Winforms. In WPF that can be achieved easily if you use XAML code. Even in code behind, you can always build a Style or Template from XAML string (with the help of XamlReader). This approach is good for complex scenario but in this case I have another approach (don't use the XAML parser at all). This trick does render the grid which is good enough (and at best it can do for the trade-off of simplicity):
//we need an instance of Style to set to ListView.ItemContainerStyle
var style = new Style(typeof(ListViewItem));
//set the bottom border thickness to 1
var setter = new Setter(Control.BorderThickness, new Thickness(0,0,0,1));
style.Setters.Add(setter);
//set the border brush
var borderBrush = new LinearGradientBrush { StartPoint = new Point(0,0),
EndPoint = new Point(1,0)};
var gradStop = new GradientStop(Colors.Transparent, 0.001);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Green, 0.001);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Green, 0.999);
borderBrush.GradientStops.Add(gradStop);
gradStop = new GradientStop(Colors.Transparent, 0.999);
borderBrush.GradientStops.Add(gradStop);
setter = new Setter(Control.BorderBrush, borderBrush);
style.Setters.Add(setter);
yourListView.ItemContainerStyle = style;
Note that the default inner Border of each ListViewItem has a hard-coded CornerRadius of about 2, so by setting just the bottom BorderBrush to a solid brush such as Brushes.Green will show a little upwards curly line at the 2 ends of the bottom border. You can try it yourself. If this result is acceptable, the code can be shorter and simpler (because you don't have to define the GradientBrush to cut-off the 2 curly ends) like this:
setter = new Setter(Control.BorderBrush, Brushes.Green);
style.Setters.Add(setter);
If the behavior is still not what you want. You should try the approach I mentioned about using XamlReader to parse a XAML string and get an instance of whatever you want in codebehind. (you can search it yourself, it's easy to have some result).
I suggest you see this link, it contains a dynamic GridView created in code-behind that can be useful for your specific case. For the code sample that you provided, you didn't add ShowGridLines property.

WPF binding to a function?

Let me start by saying I am very new to WPF so be gentle.
It seems like this should be easy but I am just missing something. I have implemented INotifyPropertyChanged on a few classes/properties and started binding them to elements in XAML but now I have a little more complex binding to make then updating text or changing a color. What I need is when the Alarm property of my object is set to true I need to change colors, start an animation, create and display other elements in the control. I thought I could just call a function in my control when the property is changed but since WPF hides how an element is "bound" to the model's property I am not sure how to wire that up. Is there a better way to perform this type of more complex response to a property change? If not are there any samples out there? I have not been able to find anything close to what I am looking for but I may not be searching with the correct terms.
What I need is when the Alarm property of my object is set to true I
need to change colors, start an animation, create and display other
elements in the control.
Change colors: Bind the Color/Foreground of the element you want to change the color of, to the boolean that sets the alarm, and add an IValueConverter in the binding that returns a Brush based on the boolean.
Start an animation: Use a (data)trigger on whichever element needs to be animated, in that trigger, use a Storyboard to define the animation you want.
create and display other elements in the control: that really depends on how well you did your MVVM, if the elements are a visualisation of an ObservableCollection through a ListBox/ListView/ItemsControl (which it should), wire up a Command to whatever sets the alarm on/off (the Button class has a Command property built in, other UIElements may require the use of System.Windows.Interactivity) and in the method that this Command will point to, add a new item to the ObservableCollection, the ItemsControl will automatically reflect the change by adding a new control.
Of course this is just raw information, and you're probably not familiar will all these things, that's when Google comes into play ;)
HTH,
Bab.
For complex behaviour in response to a property changed event, you should use the following approach: (I'm typing this freestyle so pardon any minor syntax errors)
class MyClass : INotifyPropertyChanged
{
//Presumably you've already done this part
private object _myProperty = null;
public object MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
NotifyPropertyChanged("MyProperty");
}
}
public MyClass()
{
this.PropertyChanged += My_PropertyChanged;
}
private void My_PropertyChanged( object sender, PropertyChangedEventArgs e)
{
if( e.PropertyName == "MyProperty" )
{
//Do Something complicated
}
}
Your timer / alarm just needs to update the bound property when it elapses. The property should then raise the PropertyChanged event to notify the GUI to update.
You should take a look at DataTriggers that get fired when a property changes in the view model. The EnterActions and ExitActions will allow you to play a Storyboard when the value of the property changes. Here's an example of how it is used MSDN. You can use a content control and style the Template or ContentTemplate to add all of your elements and have it control the Visibility or Opacity of the other elements.
I don't think you are looking at this right. Your class has logic, does calculation, enforces constraints, and enforces relationships among properties. If you have an alarm hopefully there is some business logic to deal with this and should be done in the class (not the UI). A UI is not built to handle an alarm it is built to display status and actions of that alarm. You will make new control visible in an alarm situation and hide other. On the animation I think you might want to throw an event that you listen for to start the animation. The idea there is that when an alarm is thrown to can register additional handles - you want to separate the business logic from the UI (not pull the business logic into the UI).

Add DependencyObject to control from code-behind

I want to add a DependencyObject to a control from code behind. I have searched and searched online for how to do this with absolutely no success. The DependencyObject has a DependencyProperty. I also want to set this property from code-behind.
charting:ChartBehaviors inherits directly from DependencyObject. It is a class I wrote myself. The Chart control is a Third-party control.
charting:ChartBehaviors.FloatingTooltip is the DependencyProperty. This is also a class I wrote myself.
Here is what it looks like in XAML. I want to do this in code behind so that I can turn on and off the "behavior".
<charting:Chart>
<charting:ChartBehaviors.FloatingTooltip>
<charting:FloatingTooltipBehavior
TooltipTemplate="{StaticResource tooltipTemplate}" />
</charting:ChartBehaviors.FloatingTooltip>
</charting:Chart>
You can just use the SetValue method on the object (assuming you give your chart an id of chart1).
var behave = new FloatingTooltipBehavior();
chart1.SetValue(ChartBehaviors.FloatingTooltipProperty, behave);
Another solution would be to just add an Enabled property to your behavior and then set that from the code behind.
Well, you basically instantiate necessary dependency object and use appropriate method to add it to the control. For example, to add TextBlock to the StackPanel, you write it like this:
TextBlock txtMyText = new TextBlock();
stackPanel.Children.Add(txtMyText);
If you're wanting to add certain behavior to a chart, you should just get your chart object in code and look for a property like Behaviors or something. Then you either assign a behavior (if it's one-behavior-only) or add it like to the stackpanel:
Chart myChart;
myChart.Behavior = new FloatingTooltipBehavior();
It's hard to tell the exact syntax without knowing the component.

WPF - Overriding IsVisible on my custom control

I have a custom control (an Adorner) that wraps another control (a textbox).
public class MyCustomAdorner : Decorator
{
...
public MyCustomAdorner()
{
Child = new TextBox();
}
}
I want to be able to override the VisibilityChanged so that the MyCustomAdorner's event is only fired if the Child's visiblity changes, not the actual decorator. How would I go about this?
On a first approach I would try to bind the Adorner's Visibility to the TextBox's Visibility (not sure if this one works). This way, if the textbox changes visibility, the adorner will follow. If you bind them two way, then it will work the other way around too. So if you don't want it to work both ways, make sure you don't set the Adorner's Visibility.
If binding the Visibilities together doesn't work, you can try to declare a new property (for example a bool), that manages the visibilities, and bind the two Visibilities to that bool through a Converter. And when you want to change something around the Visibilities, you set this bool to a new value.
Overriding the VisibilityChange event doesn't sound good to me, also I'm not sure if you can even do that...

Resources