2013-09-24 5 views
2

В последнее время я пытаюсь создать сетку, которая использует мои UserControls, чтобы заполнить ее. Единственная проблема, с которой я столкнулся, заключается в том, что я не могу использовать материал привязки WPF для ссылки пользователь контролирует мою сетку, поэтому мне очень сложно красиво разместить их в сетке. Мой вопрос: как я могу привязать атрибуты в моей модели ViewModel (которые хранятся в классе Block, с которыми мой объект ViewModel имеет объект), в мой блок UserControl, что позволяет использовать эти переменные (X и Y, которые являются строка и столбец сетки, позиция)?WPF и MVVM: Как использовать прикрепленные свойства в моем UserControl

Вот код моего пользовательского элемента управления:

namespace Mortal_Pets.Views 
public partial class BlockView : UserControl 
{ 

    public BlockView() 
    { 
     InitializeComponent(); 
     DataContext = new BlockViewModel(); 
    } 
} 

<UserControl x:Class="Mortal_Pets.Views.BlockView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="30" d:DesignWidth="30"> 
<Canvas Background="{Binding Block.Color}" Grid.Row="{Binding Path=Block.XPosition}" Grid.Column="{Binding Path=Block.YPosition}"> 

</Canvas> 

Вот класс ViewModel и Модель UserControl:

class BlockViewModel 
{ 
    public Block Block { get; set; } 

    public BlockViewModel() 
    { 
     Block = new Block(); 
     Block.XPosition = 5; //Does Not Work, But this is how i'd like to have it 
     Block.YPosition = 5; //Does Not Work, But this is how i'd like to have it 
     Block.Color = new SolidColorBrush(Colors.Black); 
    } 
} 

class Block 
{ 
    public int XPosition { get; set; } 
    public int YPosition { get; set; } 
    public Brush Color { get; set; } 

    public Block() 
    { 

    } 
} 

Тогда следуя вверх мы имеем мое окно:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = new MainViewModel(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     BlockView view = new BlockView(); 
     view.SetValue(Grid.ColumnProperty, 5); //This does work, but is ugly and not really usefull for what i intend to do with it 
     view.SetValue(Grid.RowProperty, 5); //This does work, but is ugly and not really usefull for what i intend to do with it 
     BoardGrid.Children.Add(view); //This does work, but is ugly and not really usefull for what i intend to do with it 
    } 
} 

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Mortal_Pets.Views" x:Class="Mortal_Pets.Views.MainWindow" 
    Title="MainWindow" Height="700" Width="600" 
Loaded="Window_Loaded"> 
<Grid x:Name="BoardGrid" Margin="10,50,10,10" Width="500" Height="500"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
     <RowDefinition Height="25"/> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
     <ColumnDefinition Width="25"/> 
    </Grid.ColumnDefinitions> 
    <Label x:Name="ComboCounter" Content="{Binding Game.ComboCounter}" HorizontalAlignment="Left" Margin="-2,-61,0,0" VerticalAlignment="Top" Width="95" Grid.ColumnSpan="4"/> 

</Grid> 

Спасибо заранее, Ник ван дер Meij

+0

Что вы спрашиваете? – meilke

+0

Мой плохой вопрос, добавленный так же, как я мог (им не родной английский спикер, извините за дерьмовый английский ..) – BattleOn

ответ

1

Понял работать на основе знаний нашел here и here. Это некрасиво, но, похоже, это единственный способ, которым это будет работать.

Вы не разделили MainViewModel (я думаю, потому что это не было необходимым для быстрого образца, который вы дали). Но так как я нуждался для связывания, и вы, скорее всего, работать с ним, вот моя быстрая версия:

class MainViewModel 
{ 
    public List<BlockViewModel> Blocks { get; set; } 

    public MainViewModel() 
    { 
     Blocks = new List<BlockViewModel> { new BlockViewModel() }; 
    } 
} 

Вам нужно обернуть сетку в ItemsControl и использовать ItemContainerStyle для связывания Grid.Column и Grid.Row:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="700" Width="600" 
     xmlns:local="clr-namespace:WpfApplication1"> 

    <ItemsControl ItemsSource="{Binding Path=Blocks}"> 
     <ItemsControl.ItemContainerStyle> 
      <Style> 
       <Setter Property="Grid.Row" Value="{Binding Block.YPosition}" /> 
       <Setter Property="Grid.Column" Value="{Binding Block.XPosition}" /> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <local:BlockView/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Grid Margin="10,50,10,10" Width="500" Height="500" ShowGridLines="True"> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="25"/> 
         <RowDefinition Height="25"/> 
         <RowDefinition Height="25"/> 
         <RowDefinition Height="25"/> 
         <RowDefinition Height="25"/> 
         <RowDefinition Height="25"/> 
        </Grid.RowDefinitions> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="25"/> 
         <ColumnDefinition Width="25"/> 
         <ColumnDefinition Width="25"/> 
         <ColumnDefinition Width="25"/> 
         <ColumnDefinition Width="25"/> 
         <ColumnDefinition Width="25"/> 
        </Grid.ColumnDefinitions> 
       </Grid> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ItemsControl>  
</Window> 

BlockView теперь выглядит следующим образом:

<UserControl x:Class="WpfApplication1.BlockView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" d:DesignHeight="30" d:DesignWidth="30">  
    <Canvas Background="{Binding Block.Color}"> 
    </Canvas> 
</UserControl> 
+0

allright ill посмотреть, если это работает как должно =) спасибо за информацию – BattleOn

+0

Я думаю, что это немного сложнее, но не так много. Надеюсь, что это работает! Дай мне знать. – meilke

+0

Он работает хорошо и эффективно, что то, что мне нужно. благодаря! – BattleOn

Смежные вопросы