按钮控件模板和 DataTriggers
Button control template and DataTriggers
在我正在处理的应用程序中,我监控了几个项目。每个项目都有几个状态(打开、关闭、更改)。
状态保存在模型中,window 的 DataContext 设置为它。
每个按钮 DataContext 都设置为 SortableBindingList 中的单个项目。
在 XAML 中,我为按钮和其中的 DataTrigerrs 创建了控件模板。
但是,有时项目只显示第一个按钮,有时只显示前三个按钮(取决于我在 DataTrigger 中放入的内容)。
当我签入 Snoop 时,我看到所有三个按钮都设置了正确的 DataContext,并且没有绑定错误。
我希望每个按钮都根据 'serverstate' 属性 的值显示其内容,但这不会发生。
我做错了什么?
控制模板转到 Window.Resources:
<ControlTemplate x:Key="buttonTemplate" TargetType="Button" >
<Border BorderThickness="1"
BorderBrush="Gray"
Margin="2"
Width="40" Height="35"
>
<Border.Background>
<SolidColorBrush Color="Brown" />
</Border.Background>
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding serverstate}" Value="0">
<Setter Property="Content">
<Setter.Value>
<TextBlock Name="a1" Text="OFF" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding serverstate}" Value="1">
<Setter Property="Content">
<Setter.Value>
<TextBlock Name="a2" Text="CHNG" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding serverstate}" Value="2">
<Setter Property="Content">
<Setter.Value>
<TextBlock Name="a3" Text="ON" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
</Setter.Value>
</Setter>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
按钮:
<Button Name="state1"
DataContext="{Binding ActiveServers[0]}"
Template="{StaticResource buttonTemplate}"
/>
<Button Name="state2"
DataContext="{Binding ActiveServers[1]}"
Template="{StaticResource buttonTemplate}"
/>
<Button Name="state3"
DataContext="{Binding ActiveServers[2]}"
Template="{StaticResource buttonTemplate}"
/>
<Button Name="state4"
DataContext="{Binding ActiveServers[3]}"
Template="{StaticResource buttonTemplate}"
/>
<Button Name="state5"
DataContext="{Binding ActiveServers[4]}"
Template="{StaticResource buttonTemplate}"
/>
这是按钮在 window 中的显示方式:
注意按钮 4 和 5 如何完全忽略数据上下文中的 属性 值。
型号:
public class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Model()
{
}
private SortableBindingList<Server> _activeServers;
public SortableBindingList<Server> ActiveServers
{
get {
if (_activeServers == null)
{
_activeServers = new SortableBindingList<Server>();
}
return _activeServers;
}
set
{
_activeServers = value;
OnPropertyChanged("serverList");
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
尝试更改 Content
属性,但不创建新的 TextBlock
:
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding serverstate}" Value="0">
<Setter Property="Content" Value="OFF"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding serverstate}" Value="1">
<Setter Property="Content" Value="CHNG"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding serverstate}" Value="2">
<Setter Property="Content" Value="ON"></Setter>
</DataTrigger>
</ControlTemplate.Triggers>
我认为问题在于,两个按钮不能使用相同的 Content
。因此,对于每个触发值,每种类型的 Content
都会出现一次。您可以使用 ContentTemplate
来避免这种情况。
所以代码应该是这样的(其他 DataTriggers
也一样)。它允许您稍后将 DataTemplates
更改为更复杂的内容。
<DataTrigger Binding="{Binding serverstate}" Value="2">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="ON" VerticalAlignment="Center"
HorizontalAlignment="Center" Foreground="White" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
在我正在处理的应用程序中,我监控了几个项目。每个项目都有几个状态(打开、关闭、更改)。 状态保存在模型中,window 的 DataContext 设置为它。 每个按钮 DataContext 都设置为 SortableBindingList 中的单个项目。 在 XAML 中,我为按钮和其中的 DataTrigerrs 创建了控件模板。 但是,有时项目只显示第一个按钮,有时只显示前三个按钮(取决于我在 DataTrigger 中放入的内容)。 当我签入 Snoop 时,我看到所有三个按钮都设置了正确的 DataContext,并且没有绑定错误。 我希望每个按钮都根据 'serverstate' 属性 的值显示其内容,但这不会发生。 我做错了什么?
控制模板转到 Window.Resources:
<ControlTemplate x:Key="buttonTemplate" TargetType="Button" >
<Border BorderThickness="1"
BorderBrush="Gray"
Margin="2"
Width="40" Height="35"
>
<Border.Background>
<SolidColorBrush Color="Brown" />
</Border.Background>
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding serverstate}" Value="0">
<Setter Property="Content">
<Setter.Value>
<TextBlock Name="a1" Text="OFF" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding serverstate}" Value="1">
<Setter Property="Content">
<Setter.Value>
<TextBlock Name="a2" Text="CHNG" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding serverstate}" Value="2">
<Setter Property="Content">
<Setter.Value>
<TextBlock Name="a3" Text="ON" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
</Setter.Value>
</Setter>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
按钮:
<Button Name="state1"
DataContext="{Binding ActiveServers[0]}"
Template="{StaticResource buttonTemplate}"
/>
<Button Name="state2"
DataContext="{Binding ActiveServers[1]}"
Template="{StaticResource buttonTemplate}"
/>
<Button Name="state3"
DataContext="{Binding ActiveServers[2]}"
Template="{StaticResource buttonTemplate}"
/>
<Button Name="state4"
DataContext="{Binding ActiveServers[3]}"
Template="{StaticResource buttonTemplate}"
/>
<Button Name="state5"
DataContext="{Binding ActiveServers[4]}"
Template="{StaticResource buttonTemplate}"
/>
这是按钮在 window 中的显示方式:
注意按钮 4 和 5 如何完全忽略数据上下文中的 属性 值。
型号:
public class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Model()
{
}
private SortableBindingList<Server> _activeServers;
public SortableBindingList<Server> ActiveServers
{
get {
if (_activeServers == null)
{
_activeServers = new SortableBindingList<Server>();
}
return _activeServers;
}
set
{
_activeServers = value;
OnPropertyChanged("serverList");
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
尝试更改 Content
属性,但不创建新的 TextBlock
:
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding serverstate}" Value="0">
<Setter Property="Content" Value="OFF"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding serverstate}" Value="1">
<Setter Property="Content" Value="CHNG"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding serverstate}" Value="2">
<Setter Property="Content" Value="ON"></Setter>
</DataTrigger>
</ControlTemplate.Triggers>
我认为问题在于,两个按钮不能使用相同的 Content
。因此,对于每个触发值,每种类型的 Content
都会出现一次。您可以使用 ContentTemplate
来避免这种情况。
所以代码应该是这样的(其他 DataTriggers
也一样)。它允许您稍后将 DataTemplates
更改为更复杂的内容。
<DataTrigger Binding="{Binding serverstate}" Value="2">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="ON" VerticalAlignment="Center"
HorizontalAlignment="Center" Foreground="White" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>