How to bind a checkbox and drop down in a WorkflowActivityDesigner to a parameter in the CodeActivity? - workflow-foundation-4

How can I bind a checkbox and drop down in a WorkflowActivityDesigner to a parameter in the CodeActivity? I was able to finally connect the designer with the activity using this: [Designer(typeof(ActivityDesigner1))]. But the question remains, how do I consume the values from the designer surface into
Here is my codeactivity file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.ComponentModel;
namespace WorkflowConsoleApplication1
{
[Designer(typeof(ActivityDesigner1))]
public sealed class CodeActivity1 : NativeActivity
{
// Define an activity input argument of type string
public InArgument<string> Text { get; set; }
protected override void Execute(NativeActivityContext context)
{
string text = context.GetValue(this.Text);
Console.WriteLine(this.Text);
}
}
}
Here is my designer xaml file:
<sap:ActivityDesigner x:Class="WorkflowConsoleApplication1.ActivityDesigner1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation" Height="68">
<sap:ActivityDesigner.Icon>
<DrawingBrush>
<DrawingBrush.Drawing>
<ImageDrawing>
<ImageDrawing.Rect>
<Rect Location="0,0" Size="16,16" />
</ImageDrawing.Rect>
<ImageDrawing.ImageSource>
<BitmapImage UriSource="TES16x16icon.gif" />
</ImageDrawing.ImageSource>
</ImageDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</sap:ActivityDesigner.Icon>
<Grid>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<TextBox HorizontalAlignment="Left" Height="21" Margin="34,6,0,-18" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Name="txtSubject" RenderTransformOrigin="0.5,0.5">
<TextBox.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-5.46"/>
<TranslateTransform/>
</TransformGroup>
</TextBox.RenderTransform>
</TextBox>
</Grid>
</sap:ActivityDesigner>

Partial answer available here.

Related

Problem instantiating Tab page Child Viewmodel with Prism NavigationService

We have managed to wire a child content page of a tab page to its own viewmodel in our Prism Xamarin Forms app. This works if ContactsScreenViewModel has a parameterless constructor. If we inject the NavigationService into the constructor the code doesn't compile. Does anyone know how we can solve this problem?
Visual Studio is reporting that a parameterless constructor is required
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:TabsTest.Views"
xmlns:viewmodels="clr-namespace:TabsTest.ViewModels"
x:Class="TabsTest.Views.MainPage"
Title="{Binding Title}"
UnselectedTabColor ="Gray"
SelectedTabColor="Green"
BarBackgroundColor="LightGray">
<views:ContactsScreen BackgroundColor="White" Title="Contacts">
<views:ContactsScreen.BindingContext>
<viewmodels:ContactsScreenViewModel/>
</views:ContactsScreen.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary"
Priority="1" >
</ToolbarItem>
<ToolbarItem Order="Primary"
Priority="0" >
</ToolbarItem>
</ContentPage.ToolbarItems>
</views:ContactsScreen>
</TabbedPage>
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Text;
namespace TabsTest.ViewModels
{
public class ContactsScreenViewModel
{
private INavigationService _navigationService { get; }
public ContactsScreenViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
}
}
}
<viewmodels:ContactsScreenViewModel/> is a constructor call... where do you expect the parameters to come from?
You want to either resolve the view model first (through a factory) and then attach the view to it, or make use of the ViewModelLocator to resolve the view model for you (and resolve and inject its dependencies) as described here, for example.
<TabbedPage [...]
xmlns:prism="http://prismlibrary.com"
prism:ViewModelLocator.AutowireViewModel="True">
will resolve an instance of TabbedPageViewModel and put it the BindingContext.
That one should expose an instance of ContactsScreenViewModel through a property:
<views:ContactsScreen BindingContext={Binding ThePropertyOnTabbedPageViewModel}/>
You create that instance to your liking, with all parameters and dependencies you need.

Caliburn Micro Binding on Dependency Property

I have an custom control with following DP:
public FrameworkElement NoResultContent
{
get { return (FrameworkElement)GetValue(NoResultContentProperty); }
set { SetValue(NoResultContentProperty, value); }
}
public static readonly DependencyProperty NoResultContentProperty =
DependencyProperty.Register("NoResultContent", typeof(FrameworkElement), typeof(AdvancedAutoCompleteBox), new PropertyMetadata(null));
The ControlTemplate of my custom control shows this DP in a ContentControl:
<ContentControl Content="{TemplateBinding NoResultContent}" />
It's used in a view to provide arbitrary functions:
<Controls:AdvancedAutoCompleteBox
x:Name="Box"
ItemsSource="{Binding Persons}"
SelectedItem="{Binding SelectedPerson}"
Watermark="Search here">
<Controls:AdvancedAutoCompleteBox.NoResultContent>
<StackPanel>
<Button
Content="Add by ICommand"
Command="{Binding AddPerson}" />
<Button
x:Name="AddPerson"
Content="Add by Caliburn" />
</StackPanel>
</Controls:AdvancedAutoCompleteBox.NoResultContent>
</Controls:AdvancedAutoCompleteBox>
The Command-Binding to a ICommand works just fine. Buy why does it not work with Caliburn.Micro?
I also tried to attach the context to the second Button manually by cal:Bind.Model

How to remove the shadow of a button on Xamarin Forms

is it possible?
I would like to remove the shadow of the buttons on Xamarin Forms.
Thanks
For delete shadow on button Android you just need create a renderer in project Droid and set BackroundColor with transparent or other color.
For a project using PCL :
[assembly: ExportRenderer(typeof(Button),typeof(FlatButtonRenderer))]
namespace Project.Droid
{
public class FlatButtonRenderer : ButtonRenderer
{
protected override void OnDraw(Android.Graphics.Canvas canvas)
{
base.OnDraw(canvas);
}
}
}
In XAML :
<Button BackgroundColor="Transparent" Text="ClickMe"/>
Explaining with more detail.
using Android.App;
using Android.Content.PM;
using Android.OS;
using Xamarin.Forms.Platform.Android;
using ProjectName.Droid;
using Xamarin.Forms;
[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(FlatButtonRenderer))]
namespace ProjectName.Droid
{
public class FlatButtonRenderer : ButtonRenderer
{
protected override void OnDraw(Android.Graphics.Canvas canvas)
{
base.OnDraw(canvas);
}
}
}
#Tonatio in your renderer instead of using
[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(FlatButtonRenderer))]
use this
[assembly: ExportRenderer(typeof(YourCustomButton), typeof(FlatButtonRenderer))]
you will have to make a CustomButton control that inherits from Xamarin.Forms.Button and then use that custom button in your xaml instead of regular button. that should do the thing
//Add references to your custom control
xmlns:controls="clr-namespace:YourNameSpace.Controls"
//Use control
<Grid>
<controls:YourCustomButton x:Name="_customButton"/>
</Grid>
Feel free to drop by if you need some more help.
There's a simple hack around this. Simply wrap the button in a Frame element, with HasShadow set to False
<Frame HasShadow="False" Padding="0" Margin="0">
<Button Padding="15"
Text="Log in"
TextColor="Blue"
FontSize="17" />
</Frame>
This will remove the button's shadow 😉

ObservableCollection<Double[]> and XAML

I have a class that inherits ObservableCollection< Double[] > (let's call it "TestClass"). I.e. collection of double arrays. Can I use this kind of collection in XAML. I'm trying to add items but it looks like I cannot add double arrays as items. Is this even possible?
Something like this:
<TestClass>
<x:Array Type="sys:Double">
<!-- What comes here...? -->
</x:Array>
</TestClass>
Actually, I would rather like to use ObservableCollection< Double[,] > but I think it's impossible - two-dimensional array I mean.
Help me out here... :)
First, you need a ViewModel. The ViewModel will be your container class where we insert custom double-arrays or fetch them from the database. If it's not just a lookup, you will need to implement INotifyPropertyChanged (but that's a different topic):
namespace MyCompany.Common.ViewModels
{
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class PointsArrayVM
{
private double[] _points;
public double[] Points
{
get
{
return _points;
}
set
{
_points = value;
}
}
}
}
In this example, I'll add two custom records of double[] (firstArray & secondArray). I then assign the collection to a CollectionViewSource, and (just to illustrate) I assign more records from the database to a second CollectionViewSource with the exposed MainViewModel property, List<PointsArrayVM> DatabasePoints. If it's not just a lookup, you will need an ObservableCollection instead of a List. In your XAML, under Window.Resources, add the following:
<x:Array x:Key="firstArray" Type="sys:Double"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:Double>1.1</sys:Double>
<sys:Double>1.2</sys:Double>
<sys:Double>1.3</sys:Double>
</x:Array>
<x:Array x:Key="secondArray" Type="sys:Double"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:Double>2.1</sys:Double>
<sys:Double>2.2</sys:Double>
<sys:Double>2.3</sys:Double>
</x:Array>
<x:Array x:Key="pointsArray" Type="{x:Type viewmodels:PointsArrayVM}"
xmlns:viewmodels="clr-namespace:MyCompany.Common.ViewModels;assembly=Common">
<viewmodels:PointsArrayVM Points="{StaticResource firstArray}"/>
<viewmodels:PointsArrayVM Points="{StaticResource secondArray}"/>
</x:Array>
<CollectionViewSource x:Key="customPointsCollectionViewSource" Source="{StaticResource pointsArray}"/>
<CollectionViewSource x:Key="databasePointsCollectionViewSource" Source="{Binding DatabasePoints}"/>
Now that we have our CollectionViewSources, we can add them to a CompositeCollection with CollectionContainers. In this example I'm using Points[0] as the display text, and Points1 as the selected value:
<ComboBox Text="{Binding PointsFilter}" VerticalAlignment="Top"
SelectedValuePath="Points[0]" DisplayMemberPath="Points[1]">
<ComboBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource customPointsCollectionViewSource}}"/>
<CollectionContainer Collection="{Binding Source={StaticResource databasePointsCollectionViewSource}}"/>
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
I hope this helps! For some very informative XAML tips, have a look at this site.
Regarding your second question
Yes, WPF seems to have a problem with assigning a control path to a specific point in a multi-dim array. You can however work around this by also having a Points2DArray ViewModel that contains an array of PointsArrayVM objects:
namespace MyCompany.Common.ViewModels
{
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class Points2DArrayVM
{
private PointsArrayVM[] _pointsArrays;
public PointsArrayVM[] PointsArrays
{
get
{
return _pointsArrays;
}
set
{
_pointsArrays = value;
}
}
}
}
So in your XAML, you can now put the collections of one ViewModel into the other container ViewModel:
<x:Array x:Key="pointsArray1" Type="{x:Type viewmodels:PointsArrayVM}"
xmlns:viewmodels="clr-namespace:MyCompany.Common.ViewModels;assembly=Common">
<viewmodels:PointsArrayVM Points="{StaticResource firstArray}"/>
<viewmodels:PointsArrayVM Points="{StaticResource secondArray}"/>
</x:Array>
<x:Array x:Key="pointsArray2" Type="{x:Type viewmodels:PointsArrayVM}"
xmlns:viewmodels="clr-namespace:MyCompany.Common.ViewModels;assembly=Common">
<viewmodels:PointsArrayVM Points="{StaticResource firstArray}"/>
<viewmodels:PointsArrayVM Points="{StaticResource secondArray}"/>
</x:Array>
<x:Array x:Key="points2DArray" Type="{x:Type viewmodels:Points2DArrayVM}"
xmlns:viewmodels="clr-namespace:MyCompany.Common.ViewModels;assembly=Common">
<viewmodels:Points2DArrayVM PointsArrays="{StaticResource pointsArray1}"/>
<viewmodels:Points2DArrayVM PointsArrays="{StaticResource pointsArray2}"/>
</x:Array>
<CollectionViewSource x:Key="customPointsCollectionViewSource" Source="{StaticResource points2DArray}"/>
Then in your ComboBox, it would be something like:
<ComboBox Text="{Binding PointsFilter}" VerticalAlignment="Top"
SelectedValuePath="PointsArrays[0].Points[0]" DisplayMemberPath="PointsArrays[0].Points[1]">
<ComboBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource customPointsCollectionViewSource}}"/>
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>

Rendering a Heterogeneous Collection of View Models in Silverlight 2

I have a hierarchy of view models representing formatted content:
public abstract class ContentPartViewModel : ViewModel
{
}
public class TextContentPartViewModel : ContentPartViewModel
{
public string Text { ... }
}
public class TitleContentPartViewModel : TextContentPartViewModel
{
}
public class HyperlinkContentPartViewModel : TextContentPartViewModel
{
public string Uri { ... }
}
I have an encompassing view model that contains a collection of ContentPartViewModels to be rendered:
public class ContentViewModel
{
public ICollection<ContentPartViewModel> ContentParts { ... }
}
I then have a ContentView that renders all parts of the content:
<UserControl ...>
<ItemsControl ItemsSource="{Binding ContentParts}"/>
</UserControl>
In an ideal world, I would just define a DataTemplate for each of the content part types and they would be rendered accordingly. However, Silverlight does not support the DataType property on the DataTemplate class, so that is not an option.
Another option would be to provide a DataTemplateSelector and do the mapping from view model type to DataTemplate myself. Alas, ItemsControl in SL2 does not have an ItemTemplateSelector property - only an ItemTemplate property.
That left me with no option but to provide an ItemTemplate that then uses a converter to turn off all the UI apart from the piece relevant to that content part:
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Text}" FontWeight="Bold" Visibility="{Binding Converter={StaticResource TitleContentPartConverter}}"/>
<TextBlock Text="{Binding Text}" Visibility="{Binding Converter={StaticResource TextContentPartConverter}}"/>
<HyperlinkButton Content="{Binding Text}" NavigateUri="{Binding Uri}" Visibility="{Binding Converter={StaticResource HyperlinkContentPartConverter}}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
This is obviously rather awful, both for performance and for readability/correctness of code. It also makes it much harder for me to format the output correctly. So, questions:
Can anyone recommend a better way to do this in SL2?
Can anyone confirm whether the situation has improved in SL3?
Thanks,
Kent
Yes. DataType in DataTemplate is not supported in Silverlight 2 or Silverlight 3.
You can work around ItemTemplateSelector in Silverlight. Please take a look at this sample.
http://silverlight.net/forums/t/12598.aspx
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
DataTemplateSelector selector = this.ItemTemplateSelector;
if (null != selector)
{
((ContentPresenter)element).ContentTemplate = selector.SelectTemplate(item, element);
}
}

Resources