VS2013安装Xamarin

Xamarin官方提供了XamarinInstaller,可以方便的下载Xamarin所需的依赖包,不过需要填写一些注册信息,当然,也可以手动下载这些依赖包,可参考下面这份XML:

http://xamarin.com/installer_assets/v3/Windows/Universal//InstallationManifest.xml

PS:一般情况下请按照该XML中提供的URL下载所需安装包,即使这些程序(如JDK)有最新版也不建议使用,以免造成对Xamarin的不兼容。

  1. JDK
    Win8.1 64bit下安装JDK的时候需要注意不要安装在Program Files (x86)Program Files文件夹下,否则Android SDK会找不到JDK路径。安装完成JDK后需要配置环境变量。

  2. Android SDK
    安装完成AndroidSDK后打开SDK Manager.exe下载工具包以及插件,其中Platform-tools,Biuld-tools需要勾选,API请按照需要自行勾选:

    另外由于谷歌被墙,可能导致无法连接到服务器,可以配一个镜像代理,在SDK Manager中点击Tools–Options,设置Http代理:

  3. Android NDK
    解压到与Android SDK相同的根目录即可。

  4. GTK
    建议用管理员权限安装。

  5. Xamarin Studio
    正常安装,Xamarin程序主体。

  6. Xamarin for Visual Studio
    正常安装,Xamarin for Visual Studio插件。

WPF异步加载BitmapImage

在WPF中异步获取HTTP图片并赋值给Image控件,遇到诸多问题,如多线程队列,资源不释放等,最终琢磨出下面的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
Uri uri = e.Argument as Uri;

using (WebClient webClient = new WebClient())
{
webClient.Proxy = null;
webClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
try
{
byte[] imageBytes = null;

imageBytes = webClient.DownloadData(uri);

if (imageBytes == null)
{
e.Result = null;
return;
}
MemoryStream imageStream = new MemoryStream(imageBytes);
BitmapImage image = new BitmapImage();

image.BeginInit();
image.StreamSource = imageStream;
image.CacheOption = BitmapCacheOption.OnLoad;
image.EndInit();

image.Freeze();
imageStream.Close();

e.Result = image;
}
catch (WebException ex)
{
e.Result = ex;
}
}
};

worker.RunWorkerCompleted += (s, e) =>
{
BitmapImage bitmapImage = e.Result as BitmapImage;
if (bitmapImage != null)
{
myImage.Source = bitmapImage;
}
worker.Dispose();
};

worker.RunWorkerAsync(imageUri);

EntityFramework5.0与WCF使用遇到的问题

在使用EntityFramework5.0,并将其作为WCF放在服务端的时候遇到了如下问题:

1. EF在客户端与服务端之间传输问题

由于将EF放在服务端,所以类必须具有DataContract属性。

服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型。

只有声明为DataContract的类型的对象可以被传送,且只有成员属性会被传递,成员方法不会被传递。WCF对声明为DataContract的类型提供更加细节的控制,可以把一个成员排除在序列化范围以外,也就是说,客户端程序不会获得被排除在外的成员的任何信息,包括定义和数据。默认情况下,所有的成员属性都被排除在外,因此需要把每一个要传送的成员声明为DataMember,如下所示。

阅读更多

资源键Key

1. 什么是资源键

资源键x:Key用作创建和引用资源的唯一标识,作用类似于名称,常出现在ResourceDictionary中且要求必须为 ResourceDictionary 内的每项定义一个键。

例:

1
2
3
4
5
6
<ResourceDictionary>
<LinearGradientBrush x:Key="fadeBrush">
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="Gray" Offset="1"/>
</LinearGradientBrush>
</ResourceDictionary>

但带有DataType的数据模板DataTemplate和带有TargetTypeStyle属于特殊情况,他们本身带有隐式键。

阅读更多

如何在WPF中停止线程

1. Abort的非及时性

使用多线程经常会遇到一个问题,如何停止这个Thread?在WPF中提供了Abort方法,但MSDN却告诉我们:

线程不一定会立即中止,或者根本不中止。 如果线程在作为中止过程的一部分被调用的 finally 块中做非常大量的计算,从而无限期延迟中止操作,则会发生这种情况。

先看下面一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public partial class MainWindow : Window
{
Thread thread;
public MainWindow()
{
InitializeComponent();
Test t = new Test();
thread = new Thread(new ThreadStart(t.Run));
thread.Start();

}

private void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("abort");
thread.Abort();
}
}

public class Test
{
public void Run()
{
while (true)
{
Console.WriteLine("Running...");
}
}
}
阅读更多

在ControlTemplate中使用VisualTreeHelper和LogicalTreeHelper

在TabControl中给TabItem定义如下的Template:

1
2
3
4
5
6
7
8
9
10
11
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Border x:Name="mainBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" Background="{TemplateBinding Background}" Margin="0">
<Border x:Name="innerBorder" BorderBrush="{StaticResource TabItem.Selected.Border}" BorderThickness="1,1,1,0" Background="{StaticResource TabItem.Selected.Background}" Margin="-1" Opacity="0"/>
</Border>
<DockPanel Margin="2,0">
<Button Click="Button_Click" DockPanel.Dock="Right" Content="X" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="Blue"/>
<ContentPresenter x:Name="contentPresenter" ContentSource="Header" Focusable="False" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
</DockPanel>
</Grid>
</ControlTemplate>

实现的效果是给每一个TabItem添加关闭按钮:

现在需要实现关闭按钮的功能,那么则需要在后台Button_Click事件中通过sender找到类型为TabItem的parent。

阅读更多

InstallShield Limited Edition for Visual Studio 2013教程

【安装篇】

  1. 打开VS2013,文件-新建-项目-已安装-模板-其他项目类型-安装和部署-启用InstallShield Limited Edition。
  2. 根据提示操作,点击步骤2的“转到下载网站”。
  3. 填写相关信息后,点击Download下载InstallShield,同时注册邮箱会收到一封邮件,里面有序列号和下载链接。
  4. 退出VS,使用管理员权限重新打开VS,在文件-新建-项目-已安装-模板-其他项目类型-安装和部署中则可以看到InstallShield Limited Edition Project,点击确定,会弹出注册对话框,输入注册邮箱中收到的序列号即可完成注册。

PS:在win8.1下可能会遇到安装InstallShield后在VS中看不到”InstallShield Limited Edition Project”,只有“启用InstallShield Limited Edition”的问题,在StackOverFlow中也有人遇到类似问题,我提出并整理这个问题后发现并不是win8.1不能安装InstallShield,从win8.1企业版更换到win8.1专业版后没有出现问题,由于没有继续在win8.1企业版下测试,所以只猜测是win8.1企业版下会出现该问题,或者是由于系统缺失文件,文件被篡改等原因,如果重新安装win8.1企业版仍不能解决,则尝试安装win8.1专业版。

阅读更多

C#调用C DLL参数问题

首先回顾一下API和C#参数类型的基本对应关系:

需要注意的是这个对应关系是传入参数的对应关系,如果是输出参数,LPSTR和LPCSTR(也就是C/C++里面的char*),对应的就要是StringBuider。

例如:int TEST(char* result)

其中result是输出参数,那么在c#中,就应该使用 int TEST(StringBuider result),而不是ref string,否则会报内存错误。

阅读更多

WPF中ListView使用GridViewColumn居中对齐的方法

在WPF中使用ListView经常会用到GridView作为视图,但是却碰到GridViewColumn不能居中对齐的问题,首先想到不使用GridViewColumn的DisplayMemberBinding属性,直接设置DataTemplate,于是尝试修改代码为:

1
2
3
4
5
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextAlignment="Center" Text="{Binding XX}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>

结果还是不行,因为TextBlock的Width是根据Text内容自动调整,没有填充整个单元格,所以需要调整填充样式。方法有两种:

【方案一】

将DataTemplate元素的MinWidth和单元格的ActualWidth绑定,这样就能让DataTemplate元素始终填满单元格:

阅读更多

WCF报错System.BadImageFormatException的解决方案

在一个WCF Service Library中,如果引用了一些32bit的dll,我们称这个WCF Service Library依赖于x86。在调试过程中,也必须将其工程编译属性调整为x86。但如果我们的编译环境是64位,运行可能就会报错BadImageFormatException:

这是因为WCF Service Library是一个dll,必须放在容器中执行,在vs调试中使用了WcfSvcHost.exe来作为一个临时容器。它位于vs安装目录下的Common7\IDE\WcfSvcHost.exe。由于系统环境是64位,所以安装vs的时候就会自动设置WcfSvcHost.exe为64位,所以当WcfSvcHost.exe运行32位dll时才会报错。解决这个问题可以使用Corflags命令.

corflags命令的详细介绍可以参考这里。它可以将程序设置在32位下工作:

操作步骤:

阅读更多