如何解决切换开关内容未显示在 DataGrid 中
我的切换开关使用自定义样式。应用了样式并且它工作正常并且显示“ON”或“OFF”。问题是当我将切换开关添加到 DataGrid
时。
DataGrid
项源绑定到模型,列 isActive
包含切换开关控件。如果 isActive
为 true
,切换将采用绿色,如果为 false
,切换将采用红色,但不显示内容文本(“ON”、“OFF”)。
资源文件中切换开关的样式:
<Style x:Key="ActivetoggleSwitch" targettype="{x:Type ToggleButton}">
<Setter Property="IsChecked" Value="False"/>
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate targettype="{x:Type ToggleButton}">
<Grid x:Name="toggleSwitch">
<Border x:Name="Border" CornerRadius="10"
Background="#C2283B"
Width="90" Height="25">
<Border.Effect>
<DropShadowEffect ShadowDepth="0.6" Direction="0" Opacity="0.3" />
</Border.Effect>
<Ellipse x:Name="Ellipse" Fill="#FFFFFFFF" Stretch="Uniform"
Margin="2 2 2 1"
stroke="Gray" strokeThickness="0.2"
HorizontalAlignment="Left" Width="22" >
<Ellipse.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="1" Opacity="0.3" Direction="260" />
</Ellipse.Effect>
</Ellipse>
</Border>
<TextBlock x:Name="txtOff" Text="{Binding TextOFF}" Margin="0 0 40 0" VerticalAlignment="Center" FontWeight="DemiBold" HorizontalAlignment="Right" Foreground="White" FontSize="10" />
<TextBlock Opacity="0" x:Name="txtOn" Text="{Binding TextON}" Margin="40 0 0 0" VerticalAlignment="Center" FontWeight="DemiBold" Foreground="White" HorizontalAlignment="Left" FontSize="10" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True" >
<Trigger.Enteractions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#34A543"
Duration="0:0:0.1" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="60 2 2 1"
Duration="0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOff"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="1.0" To="0.0" Duration="0:0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOn"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="0.0" To="1.0" Duration="0:0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.Enteractions>
<!-- some out fading -->
<Trigger.Exitactions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#C2283B"
Duration="0:0:0.1" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="2 2 2 1"
Duration="0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOff"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="0" To="1.0" Duration="0:0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOn"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="1.0" To="0.0" Duration="0:0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.Exitactions>
<Setter Property="Foreground" Value="{DynamicResource IdealForegroundColorBrush}" />
</Trigger>
<Trigger Property="IsMouSEOver" Value="False">
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource GrayBrush7}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
MainWindow.xaml:
<telerik:GridViewDataColumn x:Name="Activetoogle" IsReadOnly="True" HeaderCellStyle="{StaticResource CustomgridviewheaderCellStyle}" Header="{StaticResource ActivityTriggerSwitch}" DataMemberBinding="{Binding isActive}" Width="*">
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<StackPanel Height ="Auto" >
<ToggleButton x:Name="isActive" VerticalAlignment="Center" IsEnabled="False" Style="{StaticResource ActivetoggleSwitch}"
HorizontalAlignment="Right" Width="auto" FlowDirection="RightToLeft" IsChecked="{Binding empisActive}" Content="{Binding ToogleContent}" />
</StackPanel>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
MainWindow.xaml.cs
public MainWindow(){
InitializeComponent();
TextOFF = (string)Application.Current.Resources["NotActive"];
TextON = (string)Application.Current.Resources["IsActive"];
}
// ...
我想在切换开关的列中显示文本,我该怎么做?
注意:如果未在数据模板内创建切换开关,则此方法有效。
切换按钮应包含文本(“ON”或“OFF”)。
解决方法
TextOFF
和 TextON
属性在您的 MainWindow
中定义,而不是在网格视图列中当前项的数据上下文中定义。由于您的绑定是硬连接到当前数据上下文,因此这不起作用,属性未在那里定义。
肮脏的解决方法
您可以像下面那样更改数据上下文,这是一种非常肮脏的解决方法,我不建议这样做。它将数据上下文设置为 MainWindow
,因此 ToggleButton
起作用并利用 StackPanel
数据上下文来绑定项目。
<ToggleButton x:Name="isActive"
VerticalAlignment="Center"
IsEnabled="False"
Style="{StaticResource ActiveToggleSwitch}"
HorizontalAlignment="Right"
Width="auto"
FlowDirection="RightToLeft"
DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type YourProject:MainWindow}}}"
IsChecked="{Binding DataContext.empisActive,RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}}"
Content="{Binding DataContext.ToogleContent,RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}}" />
具有依赖属性的解决方案
您不应直接在控件模板中对属性路径使用绑定。此绑定将始终依赖于确切的属性名称 TextOFF
和 TextON
以及当前数据上下文,而是使用以下选项之一:
- 创建从
ToggleButton
派生的自定义控件,并为 On 和 Off 文本添加依赖属性。 - 为On 和Off 文本创建自定义附加属性。
在这两种情况下,您都可以从外部绑定文本。我更喜欢第一个选项,因为您的开关按钮可能有其他属性,它可以公开适合其特殊行为或外观的属性。
public class SwitchButton : ToggleButton
{
static SwitchButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(SwitchButton),new FrameworkPropertyMetadata(typeof(SwitchButton)));
}
public static readonly DependencyProperty OffTextProperty = DependencyProperty.Register(
nameof(OffText),typeof(string),typeof(SwitchButton));
public static readonly DependencyProperty OnTextProperty = DependencyProperty.Register(
nameof(OnText),typeof(SwitchButton));
public string OffText
{
get => (string)GetValue(OffTextProperty);
set => SetValue(OffTextProperty,value);
}
public string OnText
{
get => (string)GetValue(OnTextProperty);
set => SetValue(OnTextProperty,value);
}
}
现在,从模板中删除 x:Key
并将类型更改为 SwitchButton
。如果没有键,样式将是隐式的并自动应用于范围内的所有 SwitchButton
控件。另请注意,绑定现在是绑定到 TemplateBinding
的依赖属性的 SwitchButton
。
<Style TargetType="{x:Type YourProject:SwitchButton}">
<Setter Property="IsChecked"
Value="False" />
<Setter Property="HorizontalAlignment"
Value="Left" />
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type YourProject:SwitchButton}">
<Grid x:Name="toggleSwitch">
<Border x:Name="Border"
CornerRadius="10"
Background="#C2283B"
Width="90"
Height="25">
<Border.Effect>
<DropShadowEffect ShadowDepth="0.6"
Direction="0"
Opacity="0.3" />
</Border.Effect>
<Ellipse x:Name="Ellipse"
Fill="#FFFFFFFF"
Stretch="Uniform"
Margin="2 2 2 1"
Stroke="Gray"
StrokeThickness="0.2"
HorizontalAlignment="Left"
Width="22">
<Ellipse.Effect>
<DropShadowEffect BlurRadius="10"
ShadowDepth="1"
Opacity="0.3"
Direction="260" />
</Ellipse.Effect>
</Ellipse>
</Border>
<TextBlock x:Name="txtOff"
Text="{TemplateBinding OffText}"
Margin="0 0 40 0"
VerticalAlignment="Center"
FontWeight="DemiBold"
HorizontalAlignment="Right"
Foreground="White"
FontSize="10" />
<TextBlock Opacity="0"
x:Name="txtOn"
Text="{TemplateBinding OnText}"
Margin="40 0 0 0"
VerticalAlignment="Center"
FontWeight="DemiBold"
Foreground="White"
HorizontalAlignment="Left"
FontSize="10" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked"
Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#34A543"
Duration="0:0:0.1" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="60 2 2 1"
Duration="0:0:0.1" />
<DoubleAnimation Storyboard.TargetName="txtOff"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="1.0"
To="0.0"
Duration="0:0:0:0.1" />
<DoubleAnimation Storyboard.TargetName="txtOn"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="0.0"
To="1.0"
Duration="0:0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- some out fading -->
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#C2283B"
Duration="0:0:0.1" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="2 2 2 1"
Duration="0:0:0.1" />
<DoubleAnimation Storyboard.TargetName="txtOff"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="0"
To="1.0"
Duration="0:0:0:0.1" />
<DoubleAnimation Storyboard.TargetName="txtOn"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="1.0"
To="0.0"
Duration="0:0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
<Setter Property="Foreground"
Value="{DynamicResource IdealForegroundColorBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="False">
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Foreground"
Value="{DynamicResource GrayBrush7}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalContentAlignment"
Value="Center" />
</Style>
这允许您从外部绑定 Off 和 On 文本。在您的情况下,您需要使用 RelativeSource
绑定来访问 TextOFF
中的 TextON
和 MainWindow
属性。
<YourProject:SwitchButton x:Name="isActive"
VerticalAlignment="Center"
IsEnabled="False"
HorizontalAlignment="Right"
Width="auto"
FlowDirection="RightToLeft"
IsChecked="{Binding empisActive}"
Content="{Binding ToogleContent}"
OffText="{Binding TextOFF,RelativeSource={RelativeSource AncestorType={x:Type YourProject:MainWindow}}}"
OnText="{Binding TextON,RelativeSource={RelativeSource AncestorType={x:Type YourProject:MainWindow}}}"/>
,
您可以直接在 xaml 中使用字符串资源,在您的情况下使用 ViewModel 是不必要的步骤
xmlns:stringResources="clr-namespace:YourApp.Properties"
<TextBlock x:Name="txtOff" Text="{x:Static stringResources:Resources.NotActive}" Margin="0 0 40 0" VerticalAlignment="Center" FontWeight="DemiBold" HorizontalAlignment="Right" Foreground="White" FontSize="10" />
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。