[英]WPF and MVVM: How use attached properties in my UserControl
Lately ive been trying to make a grid that uses my UserControls to fill it in. The only problem i've encountered is that I cant use the WPF Binding stuff to link the user controls to my grid, making it for me very hard to nicely place them in the grid. 最近,我一直试图制作一个使用我的UserControls填充的网格。我遇到的唯一问题是我无法使用WPF Binding东西将用户控件链接到我的网格,这对我来说很难做到将它们放在网格中。 My question: How can i bind the attributes in my ViewModel (which are stored in the Block class, which my ViewModel has an object of), to my UserControl Block, allowing it to use those variables (the X and Y, which are the row and column of the grid, position)?
我的问题:如何将ViewModel中的属性(存储在ViewModel拥有对象的Block类中)绑定到UserControl Block,允许它使用这些变量(X和Y,即网格的行和列,位置)?
Here is the code of my user control: 这是我的用户控件的代码:
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>
Here is the ViewModel and Model class of the UserControl: 这是UserControl的ViewModel和Model类:
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()
{
}
}
Then following up we have my Window: 然后跟进我们的窗口:
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>
Thanks in advance, Nick van der Meij 在此先感谢Nick Van der Meij
Got it to work based on knowledge found here and here . 根据在这里和这里找到的知识使它工作。 It is not pretty but this seems to be the only way it will work.
它不是很漂亮,但这似乎是它起作用的唯一方法。
You did not share the MainViewModel
(I guess because it was not necessary for the quick sample you gave). 您没有共享
MainViewModel
(我想是因为您提供的快速示例没有必要)。 But since I needed it for binding and you will most probably work with it, here is my quick version: 但是由于我需要它进行绑定,并且您很可能会使用它,因此这里是我的快速版本:
class MainViewModel
{
public List<BlockViewModel> Blocks { get; set; }
public MainViewModel()
{
Blocks = new List<BlockViewModel> { new BlockViewModel() };
}
}
You need to wrap the grid in an ItemsControl
and use the ItemContainerStyle
for binding the Grid.Column
and Grid.Row
: 您需要将网格包装在
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>
The BlockView
now looks like this: 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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.