我正在从附加到每个项目的命令中访问ObservableCollection(这是我的ItemsSource)。
我正在尝试制作两个列表,一个包含所有对象,第二个包含用户选择的对象。
这是我的观点模型。
class ViewModel : VMBase
{
private ObservableCollection<Card> _cardsCollection;
public ObservableCollection<Card> CardsCollection
{
get { return _cardsCollection; }
set { _cardsCollection = value; }
}
static private ObservableCollection<Card> _pickedCards;
static public ObservableCollection<Card> PickedCards
{
get { return _pickedCards; }
set { _pickedCards = value;
NotifyPropertyChanged("PickedCards");
}
}
}
class Card : VMBase
{
public string Name { get; set; }
public Card(string name, int cost, CardType type, CardRarity rarity)
{
this.Name = name;
this.BackgroundImage = String.Format("/Images/Cards/{0}.png", name);
this.PickCardCommand = new MvvmCommand();
this.PickCardCommand.CanExecuteFunc = obj => true;
this.PickCardCommand.ExecuteFunction = PickCard;
}
public MvvmCommand PickCardCommand { get; set; }
public void PickCard(object parameter)
{
PickedCards.Add(currentCard);
//Above Does not work, not accessible
CreateDeckModel.PickedCards.Add(currentCard);
//Above does work but only if Collection is static
//but if collection is static I am unable to call NotifyPropertyChanged()
}
}
这是我的带有绑定的XAML文件
<GridView Grid.Row="1" ItemsSource="{Binding CardsCollection, Mode=TwoWay}">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<Button Height="258" Width="180" Content="{Binding}" Margin="0,0,0,0"
Command="{Binding PickCardCommand}" CommandParameter="{Binding}">
<Button.Template>
<ControlTemplate>
<StackPanel Orientation="Vertical">
<Border BorderThickness="2" BorderBrush="White" Height="258" Width="180">
<Border.Background>
<ImageBrush ImageSource="{Binding BackgroundImage}" />
</Border.Background>
</Border>
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
这是我的MvvmCommand类
class MvvmCommand : ICommand
{
public Predicate<object> CanExecuteFunc { get; set; }
public Action<object> ExecuteFunction { get; set; }
public void Execute(object parameter)
{
ExecuteFunction(parameter);
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return CanExecuteFunc(parameter);
}
}
}
有没有办法从Item或DataContext访问ItemsSource,或者为ViewModel Class访问make命令?
答案 0 :(得分:2)
您可以通过将xaml文件中的按钮更改为以下命令,将Command指向ViewModel类:
<Button Height="258" Width="180" Content="{Binding}" Margin="0,0,0,0" Command="{Binding DataContext.PickCardCommand,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type vw:ViewClass}}}" CommandParameter="{Binding}">
在RelativeSource绑定中,您需要更改以下内容:
vw 是View的命名空间,必须使用xaml文件中的其他命名空间声明。
ViewClass 是您班级的名称。
然后你显然需要将Command从Card类移到ViewModel类。
Windows Phone
<GridView x:Name="myGridView" Grid.Row="1" ItemsSource="{Binding CardsCollection, Mode=TwoWay}">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<Button Height="258" Width="180" Content="{Binding}" Margin="0,0,0,0"
Command="{Binding ElementName=myGridView,
Path=DataContext.PickCardCommand}" CommandParameter="{Binding}">
<Button.Template>
<ControlTemplate>
<StackPanel Orientation="Vertical">
<Border BorderThickness="2" BorderBrush="White" Height="258" Width="180">
<Border.Background>
<ImageBrush ImageSource="{Binding BackgroundImage}" />
</Border.Background>
</Border>
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
您将看到我现在已经命名了GridView,然后在绑定中使用GridView的名称作为ElementName。我相信这应该有用。
答案 1 :(得分:0)
您可以在创建时将Add
PickedCards
Card
方法传递给class Card : VMBase
{
private readonly Action<Card> _addCard;
public Card(..., Action<Card> addCard)
{
...
_addCard = addCard;
this.PickCardCommand = new MvvmCommand();
this.PickCardCommand.CanExecuteFunc = obj => true;
this.PickCardCommand.ExecuteFunction = PickCard;
}
public MvvmCommand PickCardCommand { get; set; }
public void PickCard(object parameter)
{
_addCard(this);
}
}
:
var card = new Card(..., ..., ..., ..., PickedCards.Add)
然后当你创建卡片时:
{{1}}
答案 2 :(得分:-1)
您可以将集合绑定到Command参数。命令参数当前绑定到Item DataSource而不是集合
CommandParameter="{Binding}"
而是使用RelativeBinding并绑定到grid
的itemSource