Я создал пользовательский элемент управления, который выглядит как плитка. Создал другой пользовательский элемент управления с именем TilePanel, который служит контейнером по умолчанию для плиток. И, наконец, сам интерфейс, который выглядит как экран запуска окна. Я использовал RelayCommand связать мои TileCommandsRelayCommand не получает правильную модель
Здесь представлены коды:
Tilev2.xaml
<UserControl x:Class="MyNamespace.Tilev2"
Name="Tile"....
>
...
<Button x:Name="btnTile" Style="{StaticResource TileStyleButton}" Command="{Binding ElementName=Tile, Path=TileClickCommand}" >
</Button>
</UserControl>
Tilev2.xaml.cs
public partial class Tilev2 : UserControl
{
public Tilev2()
{
InitializeComponent();
}
//other DPs here
public ICommand TileClickCommand
{
get { return (ICommand)GetValue(TileClickCommandProperty); }
set { SetValue(TileClickCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for TileClickCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TileClickCommandProperty =
DependencyProperty.Register("TileClickCommand", typeof(ICommand), typeof(Tilev2));
}
}
Затем я создал Пользовательское управление TilePanel как контейнер плитки
TilePanel.xaml
<UserControl x:Class="MyNamespace.TilePanel"
...
>
<Grid>
<ScrollViewer>
<ItemsControl Name="tileGroup"
ItemsSource="{Binding TileModels}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local2:Tilev2 TileText="{Binding Text}"
TileIcon="{Binding Icon}"
TileSize="{Binding Size}"
TileFontSize="{Binding FontSize}"
Background="{Binding Background}"
TileCaption="{Binding TileCaption}"
TileCaptionFontSize="{Binding TileCaptionFontSize}"
TileClickCommand="{Binding TileCommand}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>
TilePanel.xaml.cs
public partial class TilePanel : UserControl
{
public TilePanel()
{
InitializeComponent();
DataContext = new TilePanelViewModel();
}
public TilePanelViewModel ViewModel
{
get { return (TilePanelViewModel)this.DataContext; }
}
}
Мои ViewModel для TilePanel
TilePanelViewModel.cs
public class TilePanelViewModel: ViewModelBase { private ObservableCollection _tileModels;
public ObservableCollection<TileModel> TileModels
{
get
{
if (_tileModels == null)
_tileModels = new ObservableCollection<TileModel>();
return _tileModels;
}
}
}
Тогда моя плитка модель
TileModel.cs
public class TileModel : BaseNotifyPropertyChanged
{
//other members here
ICommand tileCommand { get; set; }
//other properties here
public ICommand TileCommand
{
get { return tileCommand; }
set { tileCommand = value; NotifyPropertyChanged("TileCommand"); }
}
}
}
Это мой Старт.экр View, где должны отображаться TilePanels с плиткой ...
StartScreen.xaml
<UserControl x:Class="MyNamespace.StartMenu"
... >
<Grid>
<DockPanel x:Name="dockPanel1" Grid.Column="0" Grid.Row="1" Margin="50,5,2,5">
<local:TilePanel x:Name="tilePanel"></local:TilePanel>
</DockPanel>
</Grid>
</UserControl>
StartScreen.xaml.cs
public partial class WincollectStartMenu : UserControl, IView<StartMenuViewModel>
{
public WincollectStartMenu()
{
InitializeComponent();
}
public StartMenuViewModel ViewModel { get { return (DataContext as StartMenuViewModel); } }
private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
ViewModel.Tile = tilePanel.ViewModel.TileModels;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
return;
}
}
В моем начальном экране ViewModel, я использовал ObservableCollection Плитка и использовать Tile.Add (плитка); заполнить свой стартовый экран с плитками внутри TilePanel ...
StartMenuViewModel.cs
TileModel tile = new TileModel() { Text = "Testing1", FontSize = 11, Size = TileSize.Medium, Background = (SolidColorBrush)new BrushConverter().ConvertFromString("#039BE5"), Tag="Something" };
tile.TileCommand = new RelayCommand(
p => Tile_TileClick(tile.Tag),
p => true
);
temp.Add(tile);
Теперь проблема, если добавить новый код ниже, плитка = новый TileModel() { ...} tile.TileCommand = new RelayCommand (...), даже если бы я нажал на первую плитку, мой Tile_TileClick() получит информацию второй плитки (или вставил последнюю плитку) ...
Я что-то не так? Или я все делаю неправильно ...?
Прежде всего, СПАСИБО ВАМ ТАК МОЖНО, чтобы указать на многие из моих ошибок. Я действительно очень ценю это. Я довольно новичок в WPF, не говоря уже о MVVM. Причина, почему я использую пользовательский контроль вместо пользовательского элемента управления, - это то, что я не слишком хорошо знаком со стилями. Если я буду оценивать себя, это будет 3 из 10, поэтому я продолжал использовать пользовательский контроль. На самом деле, спасибо за это. Я буду переконфигурировать свой пользовательский элемент управления на пользовательский элемент управления, используя ваши направляющие линии. Еще раз спасибо! –