Silverlight Element Binding - c#

I have a custom component, ExportCommandButton, that has two attached properties. This component is designed to be attached to a button. When clicked, the component would initiate the export method of the grid (Telerik RadGridView). The problem I have is how can I pass the grid to the component via one of the attached properties? I've tried element to element binding, but the GridView set property never fires. How do you bind to a control and not a property of the control?
<Button IsEnabled="{Binding Loaded}"
cmd:ExportCommandButton.GridView="{Binding ElementName=MyGrid}"
cmd:ExportCommandButton.Converter="{StaticResource MyConverter}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Source="/Assets/xls.png" />
<TextBlock VerticalAlignment="Center" Text="Export" Margin="5,0,0,0" />
</StackPanel>
</Button.Content>
</Button>

Your syntax seems right. The CLR property setter is not called because the binding directly updates the dependency property, without passing by the property which is here for convenience. Use the propertyChangedCallback parameter of your attached property metadata to listen for changes.

Related

Custom control binding is not updating

I'm having trouble getting my binding to work correctly. Basically I have this, call this Control1.xaml. The commented out portion of the code binds correctly and updates as expected.
<progControls:CalibrationSummary
</progControls:CalibrationSummary>
<!--<TextBlock Text="{Binding Path=NumberOfCalibrations, Mode=OneWay}"/>-->
However, if I put that commented code in a custom control called CalibrationsSummary.xaml, I cannot bind this to NumberOfCalibrations.
Here's what CalibrationsSummary looks like
<Grid>
<TextBlock Text="{Binding Path=NumberOfCalibrations, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
Note that I do use RelativeSource to try to get the property associated with Control1.xaml, tried TemplateBinding also. What am I doing wrong?
CalibrationSummary has no TemplatedParent unless you have put it in a ControlTemplate.
If you don't explicitly set the DataContext of the property of CalibrationSummary somewhere, it will inherit the DataContext from its parent control (which I assume is Control1) and then you can bind any property of this control's DataContext as usual without specifying any source:
<Grid>
<TextBlock Text="{Binding Path=NumberOfCalibrations}"/>
</Grid>

Set an existing control template as Content Property in WPF Code Behind

I have a very simple XAML
Visibility="Collapsed" X1="1" Margin="-35 0 0 0" Y1="0.4">
<Label.Content>
<Slider Grid.Column="0"
Width="20"
Height="65"
IsDirectionReversed="True"
Maximum="0.1"
Minimum="-4"
Orientation="Vertical"
x:Name="Slider1"
Value="{Binding Source={x:Reference scaleFactorModifier},
Path=ZoomScaleFactor, Mode=TwoWay}" />
</Label.Content>
</Label>
</SciChart:CustomAnnotation.Content>
</SciChart:CustomAnnotation>
Now for some reason I need to set the CustomControl.Content property from code behind. Is there any possibility I move all the label control to some style and template and set the CustomControl content property at runtime with that particular style or template.
Update
Reason for using Code behind
Actually I have Annotations property in my control which could have any control in it as we required. Previously I had used hard coded annotations in my control and placed the controls manually. Now I want to bind the Annotations property. I could create a property of this type and add CustomAnnotation objects in it. But customAnnotation objects need to have labels and other controls in them, how could I do that?
If I have understood your problem correctly, I believe that you can do what you want by using a DataTemplate and a ContentControl. First, define a DataTemplate with your Label in:
<DataTemplate DataType="{x:Type YourPrefix:YourDataType}">
<!-- define your Label here -->
</DataTemplate>
Then you can set the Content property of your CustomControl to a ContentControl that has its own Content property set to an instance of an object of type YourDataType:
<ContentControl Content="{Binding InstanceOfYourDataType}" />
I'm aware that you want to do this programmatically, but that's easy enough to work out:
ContentControl contentControl = new ContentControl();
contentControl.Content = instanceOfYourDataType;
yourCustomControl.Content = contentControl;
I'm wondering if you even really need to use your CustomControl at all, but I'll leave that up to you.
I create a user control from that xaml and then set the CustomControl.Content as new instance of user control. This might not be the best solution, but this is all that I have for now.

Forcing a ListBox to re-render

Background:
I have a ListBox containing items defined by DataTemplates. Right now, if an object in the list has the property IsEditable set to true, the item's property information will be displayed inside of textboxes (via DataTemplate change), instead of textblocks (so the user can edit the content of that list item)
IsEditable is toggled on/off by a button inside of each list item. I have been told that we need to keep the state of all objects consistent, which means I can't just rebind the ItemsSource and lose everything.
Currently, I'm using this to re-render:
this.lbPoints.Dispatcher.Invoke(DispatcherPriority.Render, new Action(() => { }));
Question:
The aforementioned code snippet KIND OF does its job. By "kind of", I mean, it does eventually cause my data to become re-rendered, but only when I scroll to the bottom of the list and then scroll back up to the item i'm trying to re-render.
1) How can I re-render the data immediately without having to scroll around to get it to show up?
The guys commenting are right that you're going about this the wrong way... there is rarely a need to force a ListBox to re-render. You're probably causing yourself some additional grief trying to switch the DataTemplates (although it is possible). Instead of that, think about data binding the TextBox.IsReadOnly property to your IsEditable property:
<TextBox IsReadOnly="{Binding IsEditable}" Text="{Binding Text}" />
Another alternative is to use a BooleanToVisibilityConverter to show a different Grid in your DataTemplate when your IsEditable property is true. Unfortunately, that Converter doesn't have an inverse operation, so you could create an IsNotEditing property to bind to the Grid in the DataTemplate that is originally displayed. I'm not sure if that's clear... see this example:
<DataTemplate DataType="{x:Type YourPrefix:YourDataType}">
<Grid>
<Grid Visibility="{Binding IsNotEditing, Converter={StaticResource
BooleanToVisibilityConverter}}">
<!-- Define your uneditable UI here -->
</Grid>
<Grid Visibility="{Binding IsEditing, Converter={StaticResource
BooleanToVisibilityConverter}}">
<!-- Define your editable UI here -->
</Grid>
</Grid>
</DataTemplate>
You could also define your own BooleanToVisibilityConverter class that has an IsInverted property, so that you can just use the one IsEditing property. You'd need to declare two Converters still, like this:
<Converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<Converters:BoolToVisibilityConverter x:Key="InvertedBoolToVisibilityConverter"
IsInverted="True" />
Then your XAML would be like this:
<Grid Visibility="{Binding IsEditing, Converter={StaticResource
InvertedBoolToVisibilityConverter}}">
<!-- Define your uneditable UI here -->
</Grid>
<Grid Visibility="{Binding IsEditing, Converter={StaticResource
BoolToVisibilityConverter}}">
<!-- Define your editable UI here -->
</Grid>

Binding a control's x:Name

When I add
<TextBlock Text="{Binding SettingName}" TextWrapping="Wrap" Margin="10,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" />
Everuthing is ok. But when
<TextBlock x:Name="{Binding SettingTextBlockName}" Text="{Binding SettingName}" TextWrapping="Wrap" Margin="10,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" />
constructor are breaking.
But I need different names in all elements.
x:Name is a special property. As a matter of fact it's not a property at all, it's an attribute that maps the name or id property of the element to x:Name. Binding only works when applied to a DependencyProperty, so it cannot work on x:Name. It must be set manually.
If you want to distinguish between objects in runtime, you can set the Tag attribute, which tolerates everything.
more on x:Name: http://msdn.microsoft.com/en-us/library/ms752290.aspx
You should use FrameworkElement.Tag property, according to MSDN
FrameworkElement.Tag gets or sets an arbitrary object value that can
be used to store custom information about this element.
What use is the Tag property in .net

ToolTip is null. How do I access it?

In my custom control I want to programmaticaly enable or disable tooltip depending on options. Here is how my icon defined in template:
<Image x:Name="PART_IconImage" Stretch="None" VerticalAlignment="Top" HorizontalAlignment="Center" Source="{TemplateBinding Icon}"
ToolTipService.ToolTip="{TemplateBinding Caption}" />
I'm using this code to access ToolTip and to enable/disable it:
// Enable tooltip when caption not shown
if (this.IconImage != null)
{
var toolTip = ToolTipService.GetToolTip(this.IconImage) as ToolTip;
if (toolTip != null)
toolTip.IsEnabled = this.CaptionVisibility.HasValue
? (this.CaptionVisibility.Value == Visibility.Collapsed)
: (this.ParentToolbar.CaptionsVisibility == Visibility.Collapsed);
}
GetToolTip returns null. Any idea why?
P.S. I was following this advice here: How to programmatically access ToolTipService of a Silverlight FrameworkElement?
But it doesn't work for me.
Are you sure that ToolTipService.GetToolTip is returning null, as opposed to returning something other than a ToolTip?
I did a quick experiment with code similar to yours and found that ToolTipService.GetToolTip returned a string. I was of course binding ToolTipService.ToolTip to a string dependency property. I suspect you're also getting a string back from GetToolTip, but the as ToolTip you have added after the call to this method nulls out this string.
One way to programmatically disable the tooltip is to bind it to a property on the view-model which contains the tooltip text if the tooltip should be shown or null if the tooltip should not be shown.
Alternatively, you can use a ToolTip, instead of a string, as the tooltip for your control. That way you should be able to access the ToolTip object and enable/disable it in your code above:
<Image x:Name="PART_IconImage" Stretch="None" VerticalAlignment="Top" HorizontalAlignment="Center" Source="{TemplateBinding Icon}">
<ToolTipService.ToolTip>
<ToolTip>
<TextBlock Text="{TemplateBinding Caption}" />
</ToolTip>
</ToolTipService.ToolTip>
</Image>
Why don't you simply bind property below with a bool property?
ToolTipService.IsEnabled
Then whenever you want to disable/enable simply change the binded property
< Image ToolTipService.IsEnabled="{Binding Path=SomeProperty}">
 
Also take a look at How do you disable tooltips in code at runtime

Categories

Resources