【发布时间】:2015-05-19 18:04:55
【问题描述】:
编辑:因为我得到的建议太多,所以我首先考虑逐步更改它,所以我的第一个问题是将动态按钮从 ViewModel 获取到 View。
我正在编写一个 WP 8.1 游戏应用程序。所以从MainPage.xaml 我的游戏导航到GamePage.xaml。在OnNavigatedTo 方法中我有这样的代码。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// Initialize GamePageViewModel
gmPageViewModel = new GamePageViewModel(this);
this.DataContext = gmPageViewModel;
}
首先在视图中,我为网格设置了 DataContext,我将 DataContext 设置为
<Grid
DataContext="{Binding GamePageVM, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<StackPanel Orientation="Horizontal" Grid.Row="1" >
<TextBlock Text="{Binding Value, Mode=TwoWay}"/>
<TextBlock Text="{Binding Moves, Mode=TwoWay}" />
</StackPanel>
<Canvas x:Name="GameCanvas" Grid.Row="2"
DataContext="{Binding ButtonItems,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}">
<ItemsControl >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding TopLeftX}"/>
<Setter Property="Canvas.Top" Value="{Binding TopLeftY}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="{Binding Width}"
Height="{Binding Height}"
Command="{Binding ButtonClickCommand}"
CommandParameter="{Binding Content,
RelativeSource={RelativeSource Self}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</Grid>
所以这是我的视图,现在我根据某些游戏标签生成一些随机按钮,可以是 5,也可以是 15,但条件是按钮不应相互重叠。
因此,在 ViewModel 中,我有一个名为 ButtonItems 的属性,它绑定到 Canvas DataContext,“Value”和“Moves”绑定到代码中的两个 TextBlock。
视图模型:
public ObservableCollection<ButtonPosition> ButtonItems{...}
public string Moves{...}
public string Value {...}
public GamePageViewModel GamePageViewModels{...}
public GamePageViewModel()
{
initTheBoard();
_moves= GameObject.Moves.ToString();
_value = GameObject.Value.ToString();
}
GameObject 是一个生成一些唯一随机数的对象。
现在这个 InItBoard() 我在其中创建动态按钮 ButtonItems
private void initTheBoard()
{
buttonItems = new ObservableCollection<ButtonPosition>();
Random r = new Random();
List<ButtonPosition> buttonPositions = new List<ButtonPosition>();
Button button;
for (int i = 0; i < numOfButtons; i++)
{
button = new Button();
bool foundOverlap = false;
int left;
int top;
ButtonPosition bp;
do
{
foundOverlap = false;
// Create a new random position for the button (subtracting the width/height
// from the X,Y so that we don't overlap the edge of the canvas)
left = r.Next(0, 500 - buttonWidth - 10);
top = r.Next(0, 500 - buttonHeight - 10);
bp = new ButtonPosition(left, top, buttonWidth, buttonHeight);
// Check each of the existing buttons for overlap
foreach (ButtonPosition existingButton in buttonPositions)
{
if (bp.Overlaps(existingButton))
{
foundOverlap = true;
break;
}
}
} while (foundOverlap);
buttonItems.Add(bp);
buttonPositions.Add(bp);
}
}
gamePageVM = this;
因此,我以这种方式填充了 viewModel,但 View 不显示任何动态创建的按钮。我发现在 Windows Phone 8.1 <ItemsControl.ItemContainerStyle> 中没有给出任何结果,所以我将其删除并放入
Canvas.Left="{Binding TopLeftX}"
Canvas.Top="{Binding TopLeftY}" 在<DataTemplate> 但没有结果。
ButtonsPositions 是另外一个类,它具有检查任何按钮是否与任何其他按钮重叠的逻辑,它有两个属性 TopLeftX,TopLeftY,即 Biding to XAML。
public class ButtonsPositions
{
public int TopLeftX { get; set; }
public int TopLeftY { get; set; }
public int Width {get; set;}
public int Height{get; set;}
}
这个Height、Width、TopLeftX 和TopLeftY 绑定到按钮的Datatemplate。 任何帮助,为什么按钮没有加载到画布中。
【问题讨论】:
标签: c# wpf xaml data-binding win-universal-app