|
See the discussion above on messaging, you are running up against the async problem in SL, you need to have you callbacks raise a message and when both messages have completed then you need to continue processing.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Thank you. I know that in theory. But, I can't find any code sample that could help me practically.
Simply, what should I do in my case? It's very simple. I call one method from WCF service and that method returns the list of strings. It looks like this in WPF:
List<string> lstSubsystems = client.GetSubsystemsByTestRunID(testRunID).ToList();
The call from WCF sevice above is only part of big method. In that big method, I have more WCF service calls after and they also return something. Therefore, it means, I need all those returning objects to be in that big method. It works normally in WPF application. But, it doesn't work in Silverlight application in that way. Yes, I wrote these 2 lines in Silverlight application:
client.GetSubsystemsByTestRunIDCompleted +=
new EventHandler<GetSubsystemsByTestRunIDCompletedEventArgs>(client_GetSubsystemsByTestRunIDCompleted);
client.GetSubsystemsByTestRunIDAsync(testRunID);
And I have callback method:
private void client_GetSubsystemsByTestRunIDCompleted(
object sender, GetSubsystemsByTestRunIDCompletedEventArgs e)
{
lstSubsystems = new List<string>();
if (e.Result != null)
lstSubsystems = e.Result;
}
But, the callback method isn't executed. It's too late. The program flow is going further.
So, I know what the problem is, but I don't know how to handle it in code. I've tried a few things I found on internet, but it doesn't help. This is really basic thing in programming - call the method from another method and use the returning object further. How can I accomplish it in Silverlight?
Thank you in advance.
|
|
|
|
|
With more details.
I have this code in big method:
private void F()
{
DatabaseServiceClient client = new DatabaseServiceClient();
client.GetSubsystemsByTestRunIDCompleted +=
new EventHandler<GetSubsystemsByTestRunIDCompletedEventArgs>(client_GetSubsystemsByTestRunIDCompleted);
client.GetSubsystemsByTestRunIDAsync(testRunID);
treeAdditionalInfo.Items.Clear();
foreach (string subsystemName in lstSubsystems)
{
TreeViewItem subsystemItem = new TreeViewItem();
subsystemItem.Header = subsystemName;
subsystemItem.FontSize = 14;
treeAdditionalInfo.Items.Add(subsystemItem);
}
List<int> lstIDsForForms = new List<int>();
client.GetFormsAndActionsCompleted +=
new EventHandler<GetFormsAndActionsCompletedEventArgs>(client_GetFormsAndActionsCompleted);
client.GetFormsAndActionsAsync(testRunID);
...
}
The code in first 2 callbacks is this:
private void client_GetSubsystemsByTestRunIDCompleted(
object sender, GetSubsystemsByTestRunIDCompletedEventArgs e)
{
lstSubsystems = new List<string>();
if (e.Result != null)
lstSubsystems = e.Result;
}
private void client_GetFormsAndActionsCompleted(
object sender, GetFormsAndActionsCompletedEventArgs e)
{
lstFormsAndActions = new List<KeyValuePair<string, List<TestLogSmall>>>();
if (e.Result != null)
lstFormsAndActions = e.Result;
}
I need to get the list after this call:
client.GetSubsystemsByTestRunIDAsync(testRunID);
And after that to get the list after this call:
client.GetFormsAndActionsAsync(testRunID);
How can I do that? What should I write?
Thank you.
|
|
|
|
|
In the first call back you can then call the next query and repeat for the third. This is not a good solution if those queries are called for any other operation than this one.
if (e.Result != null)
{
lstFormsAndActions = e.Result;
}
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
You've undestood my problem very well. Thanks.
I've already tried it and it doesn't work for me. Also, the body of method is "everywhere", which is basic incorrectness.
|
|
|
|
|
Take a look at this reply [^]from Ian, it may help (and amuse)
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
It sounds like you have a fundamental architectural problem here. As you've just found out, Silverlight applications are not WPF applications, no matter how much they look like them. There are things you take for granted in WPF that you just can't do in the same way in Silverlight, which is why it is sometimes impossible to use the same code in both types of applications. If I were you, I'd take a long hard look at the underlying infrastructure and see what - if anything - you can do to change it to suit a more asynchronous style of programming. This is going to require you to have a think about how the application flow is meant to proceed. Only you can do this - we don't know the overall architecture of your system, and the constraints it has to operate in. Now that you know what the problem is, it's up to you.
|
|
|
|
|
Ok. I'm trying to adapt my code to be async-friendly in my Silverlight application, but new problem came up. I have this function in WCF service:
[OperationContract]
List<KeyValuePair<string, List<TestLogSmall>>> GetFormsAndActions(int testRunID);
It works fine in WPF application. But, in Silverlight application doesn't. It returns the correct number of items in the list, but they are empty. Does anybody know what could be the problem with KeyValuePair object?
Thank you in advance.
|
|
|
|
|
Ok.
I've made it work in Silverlight using async approach.
Thank you guys for your help.
|
|
|
|
|
Congratulations.
|
|
|
|
|
<ListBox Margin="1,1,0,0" Grid.Row="2" Grid.Column="2" Name="lstEntityType" VerticalAlignment="Top"
SelectedItem="Binding Path=SelectedEntityList,UpdateSourceTrigger=PropertyChanged" ItemsSource="{Binding Path=SearchEntitiesTypes, Mode=OneWay}"
Width="120" Height="59" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto" HorizontalAlignment="Left" Grid.RowSpan="2">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Name="chklstEntityType" ClickMode="Press" IsChecked="true" Height="15" >
<CheckBox.Content>
<TextBlock Text="{Binding Path=SearchType}"></TextBlock>
</CheckBox.Content>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="true"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
These checkboxes should be checked by default . THe checkboxes are linked to a property. I have used mvvm pattern.
|
|
|
|
|
Set the value of the property to true before the view loads.
Make sure INotifyPropertyChanged is set on this property.
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
|
|
|
|
|
I'm trying to simulate a translucent tube with an object travelling through it. For simplicity, the tube is a rectangle and the object is a circle behind it.
I want the tube to be transparent in the middle and opaque on the edges so only the middle of the 'inside' object is clearly visible. I've got the tube's brush's OpacityMask set to a linear gradient - but it has no affect (can't see inside). I can lower the rectangle's Opacity property but that's not giving me the tube affect I'm looking for.
I'm using .NET 4.
Thanks,
Dan
<UserControl x:Class="SilverlightTest2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<LinearGradientBrush x:Key="TubeBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="Black" Offset="1"/>
<GradientStop Color="White" Offset="0.459"/>
<GradientStop Color="White" Offset="0.604"/>
</LinearGradientBrush>
</UserControl.Resources>
<Canvas x:Name="LayoutRoot" Background="White">
<Ellipse Fill="Green" Height="40" Canvas.Left="336" Stroke="Black" Canvas.Top="41" Width="40" OpacityMask="{StaticResource TubeBrush}"/>
<Rectangle Fill="Blue" Height="39" Stroke="Black" Canvas.Top="41" Width="360" OpacityMask="{StaticResource TubeBrush}"/>
</Canvas>
</UserControl>
|
|
|
|
|
An easier solution would be to use the LinearGradientBrush for the FILL and use #aarrggbb syntax for the color stops. I.e. #ff00ff00 for opaque green and #0000ff00 for transparent green. 50% transparent green would obviously be #7f00ff00.
|
|
|
|
|
Thanks! I'm still curious as to why the OpacityMask did nothing but I can dig into that later.
Dan
|
|
|
|
|
I have no idea of both. But i want to learn.
So which one i can go for?
|
|
|
|
|
WPF is desktop
Silverlight is Web
This should be enough to base you decision on. Although the lines are quite blurred. Basically they are the same with the same learning curve - steep.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
So to start sliver light what are things i need to install?
and also give some good links or books to learn silver light?
|
|
|
|
|
For learning purposes, you could start with WPF.
Silverlight is more or less a subset of WPF.
Depends on what you want to do though.
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
My latest tip/trick
|
|
|
|
|
Ok. thanks for the reply.
Can u suggest me some good links or books to learn?
|
|
|
|
|
Unfortunately, I'm not sure about WPF books.
For Silverlight, •Pro Silverlight 4" by Matthew MacDonald, is IMO, a good book.
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
My latest tip/trick
|
|
|
|
|
Why not just search the Visual Tree for it? That would be a fairly simple, and convenient, way to do it. Just start at the root visual and iterate over the tree until you find it.
|
|
|
|
|
If you take a look at the VisualTreeHelper[^] class, you can use it to iterate over the visual tree from your root element (e.g. the top level window).
|
|
|
|
|
|
Could you please explain what the string variable "name" represents? Also please tell us in what class is the GetContentControl method defined?
|
|
|
|