如何在绑定WPF DataGrid后修改单元格

时间:2014-07-31 02:55:48

标签: c# asp.net wpf datagrid

我正在尝试更新WPF数据网格中单元格的外观,我来自ASP.NET Webforms但我找不到DataBound或类似的东西我可以利用来进行更改。这在WPF中如何工作?

我只有这个:

 private void BindItems(Cars model)
 {
      ObservableCollection<CarItem> items = model.GetCarItems();
      CarsGrid.DataContext = items;

       // I tried updating below this line but the rows are not there yet (obviously), 
       // I was hoping there was like a CarsGrid.DataBind(); or something.
  }

这是复选框的标记,基本上我想启用Buy,如果绑定值为true,如果为true则禁用Rent,如果Rent为true,则相反,然后禁用Buy

<DataGridCheckBoxColumn Header="Add" Width="75" Binding="{Binding Buy}">
                    <DataGridCheckBoxColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center" />
                        </Style>
                    </DataGridCheckBoxColumn.HeaderStyle>
                </DataGridCheckBoxColumn>
                <DataGridCheckBoxColumn Header="Remove" Width="75"  Binding="{Binding Rent}">
                    <DataGridCheckBoxColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center" />
                        </Style>
                    </DataGridCheckBoxColumn.HeaderStyle>
                </DataGridCheckBoxColumn>

2 个答案:

答案 0 :(得分:2)

请参阅Style.Triggers属性。你可以这样做(见标有星星的文字):

<DataGridCheckBoxColumn Header="Add" Width="75" Binding="{Binding Buy}">
    **<DataGridCheckBoxColumn.CellStyle>
        <Style TargetType="DataGridCell">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=YourPropertyName}" Value="False">
                    <Setter Property="IsEnabled" Value="False" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridCheckBoxColumn.CellStyle>**   
    <DataGridCheckBoxColumn.HeaderStyle>
                    <Style TargetType="DataGridColumnHeader">
                        <Setter Property="HorizontalContentAlignment" Value="Center" />
                    </Style>
                </DataGridCheckBoxColumn.HeaderStyle>
    </DataGridCheckBoxColumn>
    <DataGridCheckBoxColumn Header="Remove" Width="75"  Binding="{Binding Rent}">
        <DataGridCheckBoxColumn.HeaderStyle>
            <Style TargetType="DataGridColumnHeader">
                <Setter Property="HorizontalContentAlignment" Value="Center" />
            </Style>
        </DataGridCheckBoxColumn.HeaderStyle>
</DataGridCheckBoxColumn>

答案 1 :(得分:2)

在Datagrid中启用和禁用内容的方法与WPF中的其他项目相同,只需在您想要的任何项目上设置IsEnabled属性即可。在您的情况下,您需要设置要使用的单元格样式,以覆盖用于显示复选框*和按钮的模板(在我的示例中)。

*:通常,DataGridCheckBoxColumn中使用的复选框模板只需单击一次即可选择行,只需单击一次即可切换值,而使用下面显示的方法只需单击一下即可。

请参阅以下示例,其中两个复选框启用和禁用两个按钮。显然这两个复选框不可见;它们是数据绑定到您的数据。如果你需要bool值之间的复杂逻辑,那么你可以在代码中执行它,或者使用Converter来根据上下文设置每个项目的可见性。

查看:

<Grid.Resources>
    <Style TargetType="{x:Type DataGridCell}" x:Key="BuyTemplate">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridCell}">
                    <CheckBox HorizontalAlignment="Center" IsChecked="{Binding Buy, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="{x:Type DataGridCell}" x:Key="RentTemplate">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridCell}">
                    <CheckBox HorizontalAlignment="Center" IsChecked="{Binding Rent, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <DataTemplate x:Key="BuyButtonTemplate">
        <Button HorizontalAlignment="Center" IsEnabled="{Binding Buy}" Content="BUY NOW!" />
    </DataTemplate>
    <DataTemplate x:Key="RentButtonTemplate">
        <Button HorizontalAlignment="Center" IsEnabled="{Binding Rent}" Content="Rent this car!" />
    </DataTemplate>
</Grid.Resources>
<DataGrid Name="CarGrid" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        <DataGridCheckBoxColumn Header="IsBuy" Width="75" CellStyle="{StaticResource ResourceKey=BuyTemplate}" />
        <DataGridCheckBoxColumn Header="IsRent" Width="75"  CellStyle="{StaticResource ResourceKey=RentTemplate}" />
        <DataGridTemplateColumn Header="Buy" CellTemplate="{StaticResource ResourceKey=BuyButtonTemplate}" />
        <DataGridTemplateColumn Header="Rent" CellTemplate="{StaticResource ResourceKey=RentButtonTemplate}" />
    </DataGrid.Columns>
</DataGrid>

代码隐藏:

class Car : INotifyPropertyChanged
{
    private bool buy, rent;
    public bool Buy 
    {
        get { return buy; }
        set { SetAndNotifyIfChanged(ref buy, value); }
    }
    public bool Rent 
    {
        get { return rent; }
        set { SetAndNotifyIfChanged(ref rent, value); }
    }
    public string Name { get; set; }

    public Car(string name, bool isBuy)
    {
        Name = name;
        buy = isBuy;
        rent = !isBuy;
    }

    private void SetAndNotifyIfChanged<T>(ref T original, T newValue, [CallerMemberName] string caller = null)
        where T : IEquatable<T>
    {
        if (!original.Equals(newValue))
        {
            original = newValue;

            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(caller));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

我设置了这样的项目:

List<Car> cars = new List<Car>();

cars.Add(new Car("Citroen", true));
cars.Add(new Car("Ford", true));
cars.Add(new Car("Toyota", false));

CarGrid.ItemsSource = cars;