我使用 Mono 技术创建游戏。在写的时候,我有一个问题。我需要用图片创建一个网格(4 到 5)。我想在这里应用 GridLayout 或 GridView。但我不知道如何在 GridLayout 中动态创建图像,这些图像使用 ViewModel (属性列表)进行更新。游戏过程中会改变List中SquareModel对象的属性,即图片的路径。如果您单击图像,它将改变。
我在Windows Phone中做过的类似游戏。没有问题。
我使用 Mono 技术创建游戏。在写的时候,我有一个问题。我需要用图片创建一个网格(4 到 5)。我想在这里应用 GridLayout 或 GridView。但我不知道如何在 GridLayout 中动态创建图像,这些图像使用 ViewModel (属性列表)进行更新。游戏过程中会改变List中SquareModel对象的属性,即图片的路径。如果您单击图像,它将改变。
我在Windows Phone中做过的类似游戏。没有问题。
现在 BindableGridView 的示例在https://github.com/slodge/MvvmCross/issues/37
当文件名来自视图模型时,这是我们用来在 Buttons 上绑定图像的解决方案:
1) 创建绑定
public class MvxButtonIconBinding: MvxBaseAndroidTargetBinding
{
private readonly View _view;
public MvxButtonIconBinding(View view)
{
_view = view;
}
public override void SetValue(object value)
{
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
path = Path.Combine(path, "pictures");
path = Path.Combine(path, (string)value);
if (File.Exists(path))
{
var dr = Drawable.CreateFromPath(path);
Button b = _view as Button;
var drawables = b.GetCompoundDrawables();
foreach (var d in drawables)
if (d!=null)
d.Dispose(); // To avoid "out of memory" messages
b.SetCompoundDrawablesWithIntrinsicBounds(null, dr, null, null);
}
else
{
Console.WriteLine("File {0} does not exists", path);
}
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.OneWay; }
}
public override Type TargetType
{
get { return typeof(string); }
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
}
base.Dispose(isDisposing);
}
}
2)设置绑定:
registry.RegisterFactory(new MvxCustomBindingFactory<View>("ButtonIcon", view => new MvxButtonIconBinding(view)));
3)在你的gridview/listview中使用它:
<ShopBazarAndroid.MvvmCross.MvxBindableGridView
android:layout_width="0dp"
android:layout_weight="8"
android:layout_height="fill_parent"
android:id="@+id/ArticleLayout"
android:columnWidth="170dp"
android:numColumns="auto_fit"
android:verticalSpacing="5dp"
android:horizontalSpacing="5dp"
android:stretchMode="columnWidth"
android:gravity="center"
local:MvxItemTemplate="@layout/article_buttonlayout"
local:MvxBind="{'ItemsSource':{'Path':'VisualArticles'}}" />
“article_buttonlayout”:
<Button
android:id="@+id/ButtonArticle"
android:layout_width="fill_parent"
android:layout_height="160dp"
android:gravity="bottom|center"
android:paddingBottom="5dp"
android:paddingTop="5dp"
local:MvxBind="{'Click':{'Path':'Command1'},'ButtonIcon':{'Path':'Item.PictureFileName'}}"
android:textSize="14dip"
android:textColor="@drawable/ToggleButtonSelector" />
其中“Item”是我的对象,“PictureFileName”是本地文件系统上的文件名。
我是 C# 新手,如果您发现错误,请多多包涵 :)
Android 中有一个 GridView - 但我个人从未在 mvvmcross 中使用带有数据绑定的 GridView - 但我听说添加它非常简单 - 请参阅https://github.com/slodge/MvvmCross/issues/37
作为网格视图的替代方案,您可以使用垂直和水平线性布局的某种组合来构建自己的网格。您可以通过使用外部线性布局来做到这一点,例如:
<Mvx.MvxBindableLinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
local:MvxItemTemplate="@layout/listitem_row"
local:MvxBind="{'ItemsSource':{'Path':'Rows'}}"
/>
行模板包含
<Mvx.MvxBindableLinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
local:MvxItemTemplate="@layout/listitem_cell"
local:MvxBind="{'ItemsSource':{'Path':'Cells'}}"
/>
和只包含ImageView
无论您使用 GridView 还是 LinearLayouts,您都应该能够为您的各个 ImageView 方块构建一个容器。
一旦准备好,那么更改每个正方形中显示的图像应该非常简单 - 它应该只是将 ImageView 的 AssetImagePath 绑定到代表正方形的 ViewModel 对象上的属性的情况。
IE。如果您的 ViewModel 是:
public class MyViewModel : MvxViewModel
{
public List<GameRow> Rows {get;private set;}
}
其中 GameRow 是:
public class GameRow : MvxNotifyProperty
{
public List<GameSquare> Cells {get;private set;}
}
其中 GameSquare 是:
public class GameSquare : MvxNotifyProperty
{
private string _icon;
public string Icon
{
get { return _icon; }
set { _icon = value; RaisePropertyChanged(() => Icon);
}
}
那么每个 ImageView 显示上的绑定应该是这样的:
{'AssetImagePath':{'Path':'Icon'}}
显然,您可能不想直接在 ViewModel 中使用图标路径——您可能更喜欢使用枚举。如果您这样做,那么您可能希望使用一个ValueConverter
或自定义绑定来根据当前枚举值显示正确的图像。
请参阅如何使用 Mvvmcross 将图像 src 绑定到资源可绘制图像中的问题和答案?了解更多信息。