Custom activity in WF 4.0: WorkflowItemsPresenter wont show converted array - c#

we have an Array which is converted via a Binded Converter:
else if (TTools.IsOfBaseClass(value.GetType(), typeof(System.Activities.Presentation.Model.ModelItemCollection)))
{
OurBaseClass[] test = (value as ModelItemCollection).GetCurrentValue() as OurBaseClass[];
List<OurBaseClass> listOfArray = new List<OurBaseClass>();
foreach (OurBaseClass item in test)
{
listOfArray.Add(item);
}
return listOfArray;
}
the convertion works well but it is not shown in our dynamically gui
gui code with bindings:
<sap:WorkflowItemsPresenter xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation" Grid.Column="0" Name="MyArray" Items="{Binding Path=ModelItem.MyArray}" MinWidth="150" Margin="0">
<sap:WorkflowItemsPresenter.SpacerTemplate >
<DataTemplate>
<TextBlock Foreground="DarkGray" Margin="30">..</TextBlock>
</DataTemplate>
</sap:WorkflowItemsPresenter.SpacerTemplate>
<sap:WorkflowItemsPresenter.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="0"/>
</ItemsPanelTemplate>
</sap:WorkflowItemsPresenter.ItemsPanel>
</sap:WorkflowItemsPresenter>
Why is the gui not shown as a List??? it works well without converter.
Thanks

Have you tried setting a breakpoint in the converter?
I think the first problem may be that ModelItem.MyArray is type ModelProperty, rather than ModelItemCollection.

Related

How to bind an image source in bin/debug? [duplicate]

This question already has an answer here:
How do I change an image source dynamically from code-behind in WPF with an image in Properties.Resources?
(1 answer)
Closed 1 year ago.
XAML code:
<ListView x:Name="Toolbar" Grid.Row="1" ItemsSource="{Binding List}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel MouseLeftButtonDown="Lamp_Click" Name="Lamp" Background="White" Width="34" Height="35">
<Grid Height="30">
<Image Source="images/{Binding Path}">
</Image>
<TextBlock Text="{Binding Name}" FontSize="7" TextAlignment="Center" Margin="-1,19,1,-12"></TextBlock>
</Grid>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
C# code:
public class MyClass
{
public static List<ViewModel> List{ get; set; } = GetAll();
public static List<ViewModel> GetAll()
{
// get records from data base.
}
}
This code has syntax error. How can I change images/{Binding path} to a valid. why this code has error? I'm really confused. Please help me.
<Image Source="images/{Binding Path}">
XAML doesn't support this kind of half binding thing you're doing, you either bind something or you don't. And even if it did, it wouldn't work like that because Image.Source isn't a string, it's an ImageSource.
Instead you need to create a converter that converts your Path binding (a string) to an ImageSource by instantiating a BitmapImage and setting its source to load the image asynchronously.

Computing and viewing column outside model using MVVM

I need to solve following problem using C# MVVM. I'm using following model.
And one of my UserControls got following ListBox template.
<ListBox ItemsSource="{Binding OrdersListViewViewModel.AllItems, Source={StaticResource Locator}}" SelectedItem="{Binding OrdersListViewViewModel.SelectedItem, Source={StaticResource Locator}}" Background="White">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" Margin="0 0 0 0" Height="Auto" Width="Auto" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,7,0,6" HorizontalAlignment="Left" Orientation="Horizontal">
<Image Width="25" Height="25" Margin="5 2 0 0" Source="{Binding OrdersListViewViewModel.OrderDeliveryStateImage, Mode=OneWay, Source={StaticResource Locator}}"/>
<TextBlock Margin="25,5,25,5" Text="{Binding OrdersListViewViewModel.AllItems/Customer.CustomerName, FallbackValue=N/A, Mode=OneWay, Source={StaticResource Locator}}" FontSize="20"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The list is showing all orders (customer names) loaded from database. Image which is beside the TextBlock I want to fill in with a picture. If all orderitems under the order have been delivered (Delivered=1) it should use picture1, otherwise picture2.
So I'm binding ObservableCollection<Order>. Model is generated from .tt using entity framework (db first) so it's bad idea to place computing directly into Order.cs class because of possible db updates.
My first idea was to use MSSQL Computed column but I think that's not a good aproach (there can be a lot of situations like this one in a solution) so model would be huge and complicated.
Second idea was to use a converter but it should be used for a simple tasks, not for a computation logic (which this is).
Third idea was to change ObservableCollection<Order> to ObservableCollection<Tuple<string,Order>> and somehow bind it to a view but....you know, that's a bad idea.
So my question is simple. How can I solve this issue (where to place a computation logic of this purpose) using a MVVM best practice.
Thanks.
Well after a googling around I've decided to create this solution. Maybe it will help to someone.
First I've created partial class of Order entity in order to separate files so when entity framework will update the Order entity, it will not overwrite my customizations.
Then I've created custom property which determine if the Order has been delivered. So computation logic still stays at the model.
public partial class Order
{
public bool IsOrderDelivered
{
get
{
int orderDelivered = 1;
foreach (var orderItem in this.OrderItems)
{
orderDelivered = orderDelivered * orderItem.Delivered;
}
return orderDelivered == 1 ? true : false;
}
}
}
Then I've created converter which just converts boolean to text which is why it exists and it's used the right way.
public class OrderStatusToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value == true ? #"Skins\approved.png" : #"Skins\denied.png";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
And created databinding on my new property in partial class together with converter.
<StackPanel Margin="0,7,0,6" HorizontalAlignment="Left" Orientation="Horizontal">
<Image Width="25" Height="25" Margin="5 2 0 0" Source="{Binding IsOrderDelivered, Converter={StaticResource OrderStatusToImageConverter}, Mode=OneWay}"/>
<TextBlock Margin="25,5,25,5" Text="{Binding Customer.CustomerName, FallbackValue=N/A, Mode=OneWay}" FontSize="20"/>
</StackPanel>
And finally the visual effect.

Issue with displaying images

OK, here's my issue :
I've got a custom class, with a list of items - each of which has an image path associated with it
I've added a folder WITH the images inside the project (so I suppose there are being added in the XAP too, huh?)
When I'm trying to bind the Source of an image item in XAML, it's not working.
<ListBox Margin="0,0,-12,0" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,0,0,17">
<Image Height="100" Width="100" Margin="12,0,9,0" Source="/AlbumArt/{Binding AlbumArt}"/>
<StackPanel Width="311">
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" Style="{StaticResource PhoneTextLargeStyle}"/>
<TextBlock Text="{Binding Author}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What am I doing wrong? Any ideas?
P.S.
I've also tried Source="{Binding AlbumArt}" but it's still not displaying anything.
The craziest thing is that, if I set the Source to a specific image (e.g. /AlbumArt/someImage.jpg), the image seem to work fine in Visual Studio & the Emulator.
I don't think Binding works that way. If it is not possible to prepend the string "/AlbumArt/" to your image path property (which is AlbumArt), I would suggest using a converter to do so.
Also, formatting strings only works when the target property is a string so StringFormat is out. Someone correct me if I'm wrong about StringFormat
If you have binding issues always check the output window for details. That is where information about binding errors is displayed.
This Source="/AlbumArt/{Binding AlbumArt}" won't work because it will just be treated as a string.
Without seeing your class it's hard to be certain but the property you're binding to ("AlbumArt") should be a Uri and not a string and it should be populated with a relative Uri to the image. That image should also be set to having the build action of Content.
what you have to is this..
<Image Height="100" Width="100" Margin="12,0,9,0" Source="{Binding ImagePath}"/>
as you said you have list of items( i think it would be class that also having paths of images ) so make this property in this class and for every item put the path in this property for coresponding item.
private string _ImagePath;
public string ImagePath
{
get
{
return _ImagePath;
}
set
{
_imagePath = value;
}
}
it would be better if you implement INotifyPropertyChanged in your item class.
How about getting more nesty.
private string _AlbumArt;
public string AlbumArt
{
get
{
return _AlbumArt;
}
set
{
if(_AlbumArt!=null)
_AlbumArt=#"/AlbumArt/"+ value;
}
}
and Binding
<Image Height="100" Width="100" Margin="12,0,9,0" Source="{Binding AlbumArt}"/>
I'm pretty sure you've just used the wrong path, try this one....
"/ApplicationName;component/AlbumArt/{Binding AlbumArt}"
Replace the ApplicationName section with your applications name of course. MAKE SURE TO REPLACE SPACES IN IT WITH %20

json to new listbox item in windows store app C#

I have an app for windows 8 that needs to take a Json string and deseriaizes it into DATACONTRACTS and it will display the information I wish in a Listbox that will have a max height and will scroll if greater than the max height.
The problem that im having it not so much as not being able to do it but rather not knowing how to do it.
So far I can deserialize the Json and I can specify where I want each item to go into the UI but what im trying to do is basically a for each item in the array I want it to make a new Stackpanel formatted with Textblocks that will have the information from the Json. I don't know how to this unfortunately and I don't really know what im searching for to get tutorials on how to do it
This is the code I have that takes the items from the json with a helper class and puts them in the Text of the TextBlocks.
var _FilterSaleList = new FilterSalesList();
var _Sales = await _FilterSaleList.FindSalesbyFilters();
string _SaleName = _Sales.sales[0].name.ToString();
string _SaleDescription = _Sales.sales[0].description.ToString();
string _SaleName1 = _Sales.sales[1].name.ToString();
string _SaleDescription1 = _Sales.sales[1].description.ToString();
int _TotalResults = _Sales.sales.Length;
SaleTitle.Text = _SaleName;
SaleDescription.Text = _SaleDescription;
SaleTitle1.Text = _SaleName1;
SaleDescription1.Text = _SaleDescription1;
This is the XAML code for the Listbox with 2 Stack panels already in it.
<ListBox Grid.Row="1">
<StackPanel Margin="0,0,0,5">
<TextBlock x:Name="SaleTitle" Text="" HorizontalAlignment="Center" Margin="0,0,0,5"/>
<TextBlock x:Name="SaleDescription" Text="" HorizontalAlignment="Center" MaxHeight="40" Margin="0,0,0,5" TextWrapping="Wrap"/>
</StackPanel>
<StackPanel Margin="0,0,0,5">
<TextBlock x:Name="SaleTitle1" Text="" HorizontalAlignment="Center" Margin="0,0,0,5"/>
<TextBlock x:Name="SaleDescription1" Text="" HorizontalAlignment="Center" MaxHeight="40" Margin="0,0,0,5" TextWrapping="Wrap"/>
</StackPanel>
</ListBox>
Below is an image of how I would like it to look.
even though everything works this way like I said I would like it so that each item from the json will make a new stackpanel and display the information as in the image. I don't know what its called when this is done so even a simple hint as to where to look would be great!
http://puu.sh/2biMZ
In XAML there is a very nice feature called Binding, which allows you to simply bind an object or a list of objects to visual element. This way, you don't have to "build" the graphical user interface manually in C# code.
This is a very large topic, so you should probably have a look at what is MVVM, it will help you leverage the power of Binding : http://channel9.msdn.com/Series/Building-Apps-for-Both-Windows-8-and-Windows-Phone-8-Jump-Start/Building-Apps-for-Both-Windows-8-and-Windows-Phone-8-03-Model-View-ViewModel
But for now, what you could is :
1/ Define your ListBox as following, with a DataTemplate for the ItemTemplate property :
<ListBox Grid.Row="1" x:Name="SalesListbox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,5">
<TextBlock x:Name="SaleTitle" Text="{Binding name}" HorizontalAlignment="Center" Margin="0,0,0,5"/>
<TextBlock x:Name="SaleDescription" Text="{Binding description}" HorizontalAlignment="Center" MaxHeight="40" Margin="0,0,0,5" TextWrapping="Wrap"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The DataTemplate will tell how each item of the list should be rendered. You should also notice how we used Binding for the Text properties in each textblock. It's bound to name and description which are the name of the properties in your model.
And then you can populate your ListBox with your data :
var filterSaleList = new FilterSalesList();
var salesByFilters = await filterSaleList.FindSalesbyFilters();
SalesListbox.ItemsSource = salesByFilters.sales;

WPF Noob Seeking Guidance

So, most of the time I live in ASP.NET MVC Land - however, right now I'm trying to make some analysis tools for our solution using WPF (aka, it would count lines of code, which files have tests, extracting meta data from attributes, etc). Everything is mostly going well (the reflection code I have works fine). What I'm having trouble with is the WPF ItemsControl. Compared to a tradition <asp:Repeater />, ItemsControl is completely boggling me.
My XAML:
<ItemsControl x:Name="repeaterRecentProjects">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="#094563" Margin="5" Padding="3">
<DockPanel>
<Image Source="/Content/Black-Internal-icon.png" Height="16" Width="16"></Image>
<TextBlock Margin="5,0" Text="{Binding}"></TextBlock>
</DockPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl>
The idea is that the DataTemplate contains my template, as I understand it. Then, in code I can do something like this (EDIT: Full code behind of the page):
public partial class HomeScreen : Page
{
protected bool _isProjectChosen = false;
public HomeScreen()
{
InitializeComponent();
}
protected ObservableCollection<string> someFiles = new ObservableCollection<string>();
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
someFiles.Add("SomeFile.aspx");
someFiles.Add("SomeFile2.aspx");
someFiles.Add("SomeFile3.aspx");
repeaterRecentProjects.ItemsSource = someFiles;
}
private void buttonSelectProject_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dialogSelectProject = new OpenFileDialog();
dialogSelectProject.DefaultExt = ".sln";
dialogSelectProject.Filter = "Visual Studio Solution (.sln)|*.sln";
if (dialogSelectProject.ShowDialog() == true)
{
textBlockProjectName.Text = dialogSelectProject.FileName;
_isProjectChosen = true;
buttonAnalyzeProject.IsEnabled = true;
}
someFiles.Add("AnotherString.aspx");
}
private void buttonAnalyzeProject_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Click");
}
}
However, whenever I run my application, I don't see three items in my items control, only one item. Why is this? Also, would my binding expression be correct? Since I'm not binding to a property of string, simply {Binding} should be acceptable right?
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"></StackPanel>
</ItemsPanelTemplate>
Is being added to the the ItemsControl as an item instead of setting it as the ItemsPanel, this would be the right way:
<ItemsControl>
...
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
(This is redundant anyway, because the default panel is already a vertical StackPanel)
Try setting the ItemsSource on your items control
repeaterRecentProjects.ItemsSource = someFiles;
...snipped...
I've figured out the problem, but could use some guidance on why it was occuring. When I removed the following nodes from the XAML, it works correctly:
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"></StackPanel>
</ItemsPanelTemplate>
Why was it counting that template among the items collection? My understanding was that this was simply the container item it chose to add each data template to.

Categories