Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF - Grid usage with item template

Tags:

c#

wpf

xaml

I want to place buttons that are bound to my custom field type KField, and I need 5 buttons to be placed in the shape of X - so on a 3x3 grid, I need buttons on the 4 edges, and in the middle. I have the following field type:

public class KField : ViewModelBase // ViewModelBase is a custom abstract INotifyPropertyChanged
{
    private char _text;
    private bool _isEnabled;
    private int _x;
    private int _y;    

    public int X { get { return _x; } set { _x = value; OnPropertyChanged(); } }
    public int Y { get { return _y; } set { _y = value; OnPropertyChanged(); } }
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            if (_isEnabled != value)
            {
                _isEnabled = value;
                OnPropertyChanged();
            }
        }
    }

    public char Text
    {
        get { return _text; }
        set
        {
            if (_text != value)
            {
                _text = value;
                OnPropertyChanged();
            }
        }
    }

    public DelegateCommand ClickCommand { get; set; }
}

And I use a _fields variable, that contains all the buttons and gets bound to the view:

_fields = new ObservableCollection<KField>();
_fields.Add(new KField { Text = _model.ModelFields[0], IsEnabled = true, X = 0, Y = 0});
_fields.Add(new KField { Text = _model.ModelFields[1], IsEnabled = false, X = 0, Y = 2 });
_fields.Add(new KField { Text = _model.ModelFields[2], IsEnabled = false, X = 1, Y = 1 });
_fields.Add(new KField { Text = _model.ModelFields[3], IsEnabled = true, X = 2, Y = 0 });
_fields.Add(new KField { Text = _model.ModelFields[4], IsEnabled = false, X = 2, Y = 2 });

And I created the Fields property of course:

    public ObservableCollection<KField> Fields
    {
        get { return _fields; }
        set
        {
            if (_fields != value)
            {
                _fields = value;
                OnPropertyChanged();
            }
        }
    }

And I'm using this XAML:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="376" Width="534">
    <Grid x:Name="myGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ItemsControl ItemsSource="{Binding Fields}" Margin="0,0,0,35">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Grid.Column="{Binding Y}" Grid.Row="{Binding X}" BorderThickness="0.3 " BorderBrush="Black" Command="{Binding ButtonPressed}" Content="{Binding Text}" IsEnabled="{Binding IsEnabled}">
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

However, this puts all my buttons into the first cell of the grid. The text and the enabled/disabled states work OK, so the binding does happen, but it disregards all the X and Y properties. What am I missing? How can I place these buttons the way I want to? Thank you!

like image 980
lte__ Avatar asked Jul 20 '26 06:07

lte__


1 Answers

The issue was, that the ItemsControl was just separate from the grid. If I put a grid inside the ItemsControl, and provide the binding of the coordinates in ItemContainerStyle, it works fine:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="376" Width="534">
    <ItemsControl x:Name="MyItems" ItemsSource="{Binding Fields}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button BorderThickness="0.3 " BorderBrush="Black" Command="{Binding ButtonPressed}" Content="{Binding Text}" IsEnabled="{Binding IsEnabled}">
                </Button>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Style.Setters>
                    <Setter Property="Grid.Row" Value="{Binding X}" />
                    <Setter Property="Grid.Column" Value="{Binding Y}" />
                </Style.Setters>
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</Window>
like image 62
lte__ Avatar answered Jul 21 '26 20:07

lte__