0

1 つの DataGrid 列で、x 個のクリック可能なボタンを並べて (水平に積み重ねて) 表示する必要があるという要件があります。表示される実際の数またはボタンは、その列にバインドされた値によって異なります。

下の画像はこれを示しています。左側のグリッドが現在のグリッドで、右側のグリッドが探しているものです。

現在および必要な DataGrid

グリッドは次のように ViewModel にバインドされます。

<DataGrid ItemsSource="{Binding employees}" AutoGenerateColumns="False"  >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=id}" Header="Id" />
            <DataGridTextColumn Binding="{Binding Path=numberofplatforms}" Header="No" Width="50" IsReadOnly="True" />
        </DataGrid.Columns>
    </DataGrid>

ViewModel は次のとおりです。

Public Class ViewModel

    Public Property employees As ObservableCollection(Of employee)
        Get
            Return _employees
        End Get
        Set(ByVal value As ObservableCollection(Of employee))
            _employees = value
        End Set
    End Property
    Private _employees As New ObservableCollection(Of employee)

End Class

そして、従業員は次のとおりです。

Public Class employee
    Public Property id As String
    Public Property numberofplatforms As Integer
    Public Property selectedplatform As Integer
End Class

ボタンを表示するだけでなく、ボタン自体がラジオボタンのように動作する必要があります。つまり、任意の DataGrid 行で、1 つのボタンだけが「押し下げられ」(画像の青い背景のボタン)、他のボタンは押されません (灰色の背景)。選択を変更できるように、ボタン (または形状) はクリック可能である必要があります。

「プッシュ」されるボタンは、selectedplatform プロパティに従って、ViewModel から決定されます。この例のプロパティは、ABC が 1、DEF が 1、GHI が 2 です。numberofplatforms プロパティがゼロの場合、ボタンは表示されません (JKL)。

このメカニズムを設定するにはどうすればよいですか?

4

1 に答える 1

3

コードの一部は C# で書かれていますが、問題ないことを願っています。Wpf コード:

<Window.Resources>
    <ResourceDictionary>
        <local:PositiveIntegersConverter x:Key="PositiveIntegersConverter" />
        <local:EmployeePlatformOptionConverter x:Key="EmployeePlatformOptionConverter"/>
    </ResourceDictionary>
</Window.Resources>

<DataGrid ItemsSource="{Binding employees}" AutoGenerateColumns="False" x:Name="DataGrid1">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=id}" Header="Id" />
        <DataGridTemplateColumn Header="No" IsReadOnly="True">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                        <ListBox ItemsSource="{Binding numberofplatforms, Converter={StaticResource PositiveIntegersConverter}}" SelectedItem="{Binding selectedplatform}"
                                    x:Name="ListBox1">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <Button Content="{Binding}" Command="{Binding Source={x:Reference DataGrid1}, Path=DataContext.SelectOptionCommand}">
                                        <Button.CommandParameter>
                                            <MultiBinding Converter="{StaticResource EmployeePlatformOptionConverter}">
                                                <Binding ElementName="ListBox1" Path="DataContext"/>
                                                <Binding Path="."/>
                                            </MultiBinding>
                                        </Button.CommandParameter>
                                        <Button.Style>
                                            <Style TargetType="Button">
                                                <Setter Property="Background" Value="Gray" />
                                                <Setter Property="Foreground" Value="White" />
                                                <Style.Triggers>
                                                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}"
                                                                    Value="True">
                                                        <Setter Property="Background" Value="Blue" />
                                                    </DataTrigger>
                                                </Style.Triggers>
                                            </Style>
                                        </Button.Style>
                                    </Button>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                            <ListBox.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel Orientation="Horizontal" />
                                </ItemsPanelTemplate>
                            </ListBox.ItemsPanel>
                        </ListBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

ここでは 2 つのコンバーターを使用しました。

指定された数のプラットフォームに対して正の整数を返すPositiveIntegersConverter - これらは、従業員が利用できるプラットフォーム オプションです。

SelectOptionCommand に渡したい 2 つのパラメーター (従業員と選択したプラットフォーム オプション) を EmployeePlatformOption タイプの 1 つのオブジェクトに変換する EmployeePlatformOptionConverter

public class PositiveIntegersConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var toInteger = System.Convert.ToInt32(value);
        return toInteger > 0 ? Enumerable.Range(1, toInteger) : null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class EmployeePlatformOptionConverter
    : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return new EmployeePlatformOption
            {
                Employee = values[0] as Employee,
                Platform = (int)values[1]
            };
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

カプセル化オブジェクトの使用:

public class EmployeePlatformOption
{
    public Employee Employee { get; set; }
    public int Platform { get; set; }
}

ViewModel クラスの SelectOptionCommand に選択を渡します。

public ICommand SelectOptionCommand { get; set; }
private void SelectOptionExecute(EmployeePlatformOption employeePlatformOption)
{
    if (employeePlatformOption != null && employeePlatformOption.Employee != null &&
        employeePlatformOption.Platform > 0)
    {
        employeePlatformOption.Employee.selectedplatform = employeePlatformOption.Platform;
    }
}

選択したプラットフォームの更新が画面に表示されるように、従業員はINotifyPropertyChangeインターフェイスを実装する必要があります。

于 2013-07-29T01:13:52.463 に答える