[英]WPF and MVVM: How use attached properties in my UserControl
最近,我一直試圖制作一個使用我的UserControls填充的網格。我遇到的唯一問題是我無法使用WPF Binding東西將用戶控件鏈接到我的網格,這對我來說很難做到將它們放在網格中。 我的問題:如何將ViewModel中的屬性(存儲在ViewModel擁有對象的Block類中)綁定到UserControl Block,允許它使用這些變量(X和Y,即網格的行和列,位置)?
這是我的用戶控件的代碼:
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>
這是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()
{
}
}
然后跟進我們的窗口:
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>
在此先感謝Nick Van der Meij
根據在這里和這里找到的知識使它工作。 它不是很漂亮,但這似乎是它起作用的唯一方法。
您沒有共享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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.