我试图访问每行内的布尔属性值,因此我可以使用它来设置按钮可见性,但是我无法使用DataGridTemplateColumn访问它。我能够将整个行对象转换为我传递给按钮命令的参数,但是我无法获得UseSetting值以传递给Visibility转换器。我尝试了如下图所示的文本列,但是当首次加载视图时,转换器似乎只会触发。使用断点我可以看到对UseSetting属性的后续更改不会触发转换器。我确实在DataGrid中使用的自定义类上正确设置了NotifyOfPropertyChange。
使用DataGridTemplateColumn时访问行属性的最佳方法是什么?我在DataGridTemplateColumn中创建自己的复选框而不是使用CheckboxColumn的原因是因为CheckboxColumn要求在检查之前选择行,并且我需要单击复选框才能检查。
要清楚,此视图背后没有代码。一切都在视图模型中,就像数据网格的项目源一样,它是自定义类的ObservableCollection" SharedSetting"我在下面列出。
<DataGrid MaxHeight="400" VerticalScrollBarVisibility="Auto" BorderThickness="1" CanUserAddRows="False" CanUserDeleteRows="False" BorderBrush="{DynamicResource AccentBaseColorBrush}" GridLinesVisibility="Horizontal" AutoGenerateColumns="False" ItemsSource="{Binding SharedSettings, NotifyOnSourceUpdated=True}">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}" >
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="10" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTextColumn Width="250" Header="Setting" Binding="{Binding Setting}" />
<DataGridTextColumn Width="300" Header="Value" ElementStyle="{StaticResource WrapText}" Binding="{Binding Value}" />
<DataGridTextColumn Width="75" Header="Use Setting" Binding="{Binding UseSetting, Mode=TwoWay}" x:Name="stackRowUseSetting" />
<DataGridTemplateColumn Width="50" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid Width="30" Height="30" x:Name="stackRow2">
<Button Background="Transparent" Foreground="{StaticResource AccentColorBrush}" ToolTip="Do Not Use Setting" Visibility="{Binding ElementName=stackRowUseSetting, Path=Binding, Converter={StaticResource TrueToVisibleConverter}}" BorderThickness="0" Margin="0,0,0,0" DataContext="{Binding ElementName=MainGrid, Path=DataContext}" Command="{Binding ToggleUseSettingCommand}" CommandParameter="{Binding ElementName=stackRow2,Path=DataContext}">
<iconPacks:PackIconMaterial Kind="CheckCircleOutline" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
</Button>
<Button Background="Transparent" Foreground="{StaticResource AccentColorBrush}" ToolTip="Use Setting" Visibility="{Binding ElementName=stackRowUseSetting, Path=Binding, Converter={StaticResource FalseToVisibleConverter}}" BorderThickness="0" Margin="0,0,0,0" DataContext="{Binding ElementName=MainGrid, Path=DataContext}" Command="{Binding ToggleUseSettingCommand}" CommandParameter="{Binding ElementName=stackRow2,Path=DataContext}">
<iconPacks:PackIconMaterial Kind="CheckboxBlankCircleOutline" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
</Button>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
此外,上面的XAML正是我现在所拥有的。这里有一些项目很可能是多余的而且不需要。我添加并删除了许多试图使其工作的东西,目前它有点草率。
这是带有INotifyPropertyChanged
的SharedSetting类public class SharedSetting : INotifyPropertyChanged
{
private bool _useSetting;
private object _o;
private string _value;
private string _setting;
private string _group;
public SharedSetting(string groupName, string settingName, string settingValue, object value, bool use=false)
{
Group = groupName;
Setting = settingName;
Value = settingValue;
Object = value;
UseSetting = use;
}
public SharedSetting()
{
}
public string Group
{
get { return _group; }
set
{
_group = value;
NotifyPropertyChanged();
}
}
public string Setting
{
get { return _setting; }
set
{
_setting = value;
NotifyPropertyChanged();
}
}
public string Value
{
get { return _value; }
set
{
_value = value;
NotifyPropertyChanged();
}
}
public object Object
{
get { return _o; }
set
{
_o = value;
NotifyPropertyChanged();
}
}
public bool UseSetting
{
get { return _useSetting; }
set
{
_useSetting = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
这是其中一个转换器。
public sealed class TrueToVisibleConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var flag = false;
if (value is bool)
{
flag = (bool) value;
}
var visibility = (object) (Visibility) (flag ? 0 : 2);
return visibility;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Visibility)
{
var visibility = (object) ((Visibility) value == Visibility.Visible);
return visibility;
}
return (object) false;
}
}
更新3/14/18
要解决下面提供的关于删除我的DataContext设置并使用与所有其他列一样的属性的第一个答案,这不起作用。这是我很久以前尝试的第一件事,只是为了得知DataGridTemplateColumn没有像其他列那样继承行的数据上下文(我昨天在下面的评论中感到沮丧的原因)。我已经包含了一个屏幕截图,显示了智能感知错误,说明该属性不存在,当它的使用方式与上面的列相同时。
答案 0 :(得分:0)
您为DataContext
竖立了Button
。 DataContext="{Binding ElementName=MainGrid, Path=DataContext}"
是错误的,因此请将其删除并绑定到DataGridTextColumn
中的属性。并且Command
与不在SharedSetting
中的命令的绑定使用ElementName
(正如您对DataContext
所做的那样)或RelativeSource
。
更新:
应该工作,但也可以尝试
<Button Visibility="{Binding DataContext.UseSetting, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Converter={StaticResource TrueToVisibleConverter}}" />