C# WPF无外观控制事件
我有以下课程:C# WPF无外观控制事件,c#,wpf,xaml,C#,Wpf,Xaml,我有以下课程: public class LooklessControl : Control { public List<int> IntList { get; private set; } public int CurrentInt { get; private set; } private int _index = 0; static LooklessControl() { DefaultStyleKeyProperty
public class LooklessControl : Control
{
public List<int> IntList { get; private set; }
public int CurrentInt { get; private set; }
private int _index = 0;
static LooklessControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(LooklessControl), new FrameworkPropertyMetadata(typeof(LooklessControl)));
}
public LooklessControl()
{
IntList = new List<int>();
for (int i = 0; i < 10; i++)
{
IntList.Add(i);
}
CurrentInt = IntList[_index];
}
public static readonly RoutedCommand NextItemCommand =
new RoutedCommand("NextItemCommand", typeof(LooklessControl));
private void ExecutedNextItemCommand(object sender, ExecutedRoutedEventArgs e)
{
NextItemHandler();
}
private void CanExecuteNextItemCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
public static readonly RoutedCommand PrevItemCommand =
new RoutedCommand("PrevItemCommand", typeof(LooklessControl));
private void ExecutedPrevItemCommand(ExecutedRoutedEventArgs e)
{
PrevItemHandler();
}
private void CanExecutePrevItemCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
public static readonly RoutedEvent NextItemEvent =
EventManager.RegisterRoutedEvent("NextItemEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(LooklessControl));
public event RoutedEventHandler NextItem
{
add { AddHandler(NextItemEvent, value); }
remove { RemoveHandler(NextItemEvent, value); }
}
private void RaiseNextItemEvent()
{
RoutedEventArgs args = new RoutedEventArgs(LooklessControl.NextItemEvent);
RaiseEvent(args);
}
public static readonly RoutedEvent PrevItemEvent =
EventManager.RegisterRoutedEvent("PrevItemEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(LooklessControl));
public event RoutedEventHandler PrevItem
{
add { AddHandler(PrevItemEvent, value); }
remove { RemoveHandler(PrevItemEvent, value); }
}
private void RaisePrevItemEvent()
{
RoutedEventArgs args = new RoutedEventArgs(LooklessControl.PrevItemEvent);
RaiseEvent(args);
}
private void NextItemHandler()
{
_index++;
if (_index == IntList.Count)
{
_index = 0;
}
CurrentInt = IntList[_index];
RaiseNextItemEvent();
}
private void PrevItemHandler()
{
_index--;
if (_index == 0)
{
_index = IntList.Count - 1;
}
CurrentInt = IntList[_index];
RaisePrevItemEvent();
}
}
public类LooklessControl:Control
{
公共列表IntList{get;private set;}
public int CurrentInt{get;private set;}
私有int_指数=0;
静态LooklessControl()
{
OverrideMetadata(typeof(LooklessControl),new FrameworkPropertyMetadata(typeof(LooklessControl));
}
公共LooklessControl()
{
IntList=新列表();
对于(int i=0;i<10;i++)
{
添加(i);
}
CurrentInt=IntList[_index];
}
公共静态只读路由命令NextItemCommand=
新的RoutedCommand(“NextItemCommand”,typeof(LooklessControl));
私有void ExecutedNextItemCommand(对象发送方,ExecutedRoutedEventArgs e)
{
NextItemHandler();
}
私有void CanExecuteNextItemCommand(对象发送方,CanExecuteRouteEventArgs e)
{
e、 CanExecute=true;
}
公共静态只读路由命令PreviItemCommand=
新RoutedCommand(“PrevItemCommand”,typeof(LooklessControl));
私有void ExecutedPrevItemCommand(ExecutedRoutedEventArgs e)
{
previItemHandler();
}
私有void CanExecutePrevItemCommand(对象发送方,CanExecuteRouteEventArgs e)
{
e、 CanExecute=true;
}
公共静态只读RoutedEvent NextItemEvent=
RegisterRoutedEvent(“NextItemEvent”,RoutingStrategy.Bubble,typeof(RoutedEventHandler),typeof(LooklessControl));
公共活动路线Deventhandler NextItem
{
添加{AddHandler(NextItemEvent,value);}
remove{RemoveHandler(NextItemEvent,value);}
}
私有void RaiseNextItemEvent()
{
RoutedEventArgs=新的RoutedEventArgs(LooklessControl.NextItemEvent);
RaiseEvent(args);
}
公共静态只读RoutedEvent PreviItemEvent=
RegisterRoutedEvent(“PreviItemEvent”,RoutingStrategy.Bubble,typeof(RoutedEventHandler),typeof(LooklessControl));
公共活动路线EventHandler Previitem
{
添加{AddHandler(PreviItemEvent,value);}
删除{RemoveHandler(PreviItemEvent,value);}
}
私有void RaisePrevItemEvent()
{
RoutedEventArgs args=新的RoutedEventArgs(LooklessControl.PreviItemEvent);
RaiseEvent(args);
}
私有void NextItemHandler()
{
_索引++;
if(_index==IntList.Count)
{
_指数=0;
}
CurrentInt=IntList[_index];
RaiseNextItemEvent();
}
private void PrevItemHandler()
{
_索引--;
如果(_index==0)
{
_index=IntList.Count-1;
}
CurrentInt=IntList[_index];
RaisePrevItemEvent();
}
}
该类的默认样式为Generic.xaml,如下所示:
<Style x:Key="{x:Type local:LooklessControl}" TargetType="{x:Type local:LooklessControl}">
<Setter Property="Height" Value="200"/>
<Setter Property="Width" Value="90"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:LooklessControl}">
<Border BorderBrush="Black" BorderThickness="1" Padding="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Fill="LightGray"/>
<Rectangle Grid.Row="1" Fill="Gainsboro"/>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Path Grid.Column="0" x:Name="pathLeftArrow" Data="M0,0.5 L1,1 1,0Z" Width="6" Height="14" Stretch="Fill"
HorizontalAlignment="Center" Fill="SlateBlue"/>
<TextBlock Grid.Column="1" Name="textBlock"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CurrentInt}"
HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Junction" FontSize="13"/>
<Path Grid.Column="2" x:Name="pathRightArrow" Data="M0,0 L1,0.5 0,1Z" Width="6" Height="14" Stretch="Fill"
HorizontalAlignment="Center" Fill="SlateBlue"/>
</Grid>
<ListBox Grid.Row="1" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="Transparent"
ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IntList}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如何使用户在单击pathLeftArrow时触发LooklessControl.PreviItemCommand,或单击pathRightArrow时触发LooklessControl.NextItemCommand,或单击列表框中的某个项目时通知LooklessControl新选择的项目
换句话说,如果不将x:Class添加到Generic.xaml的顶部,从而为其创建代码隐藏文件(我假设您不想这样做),那么如何处理xaml中没有命令属性(按钮之外的所有内容)的元素的事件
LooklessControl是否应该有自己的XAML文件(与创建新UserControl时得到的文件非常相似),Generic.XAML只是作为MergedActionAR作为默认模板拉入?或者有没有其他公认的方法来完成我的任务?回答您的最后一个问题:没有。无外观控件不需要任何已知的XAML。这就是lookless的意思 这里有两个选项,但我建议您使用基本为空的控件模板将元素包装在按钮中:
<ControlTemplate x:Key="contentOnlyButton" TargetType="{x:Type Button}">
<ContentPresenter />
</ControlTemplate>
...
<Button Grid.Column="0" Template="{StaticResource contentOnlyButton}"
Command="{x:Static local:LooklessControl.PrevItemCommand}">
<Path x:Name="pathLeftArrow" Data="M0,0.5 L1,1 1,0Z" Width="6" Height="14"
Stretch="Fill" HorizontalAlignment="Center" Fill="SlateBlue"/>
</Button>
这样做需要注意的一点是,不需要模板来定义您要查找的部件,因此您需要优雅地检查这种情况。在此处抛出NullReferenceExceptions
将使控件的重新序列化成为意外删除所需元素的设计人员/开发人员的一大难题。您还需要遵循标准实践,使用PART_uu语法命名所需元素,并使用TemplatePart
属性装饰类
[TemplatePart(Name = "PART_PathLeftArrow", Type = typeof(UIElement))]
[TemplatePart(Name = "PART_PathRightArrow", Type = typeof(UIElement))]
...
public class LooklessControl : Control
编辑:为了使按钮对单击做出响应,您需要为您已经定义的函数设置CommandBinding。您可以将其作为类命令绑定执行,如下所示:
static LooklessControl()
{
CommandManager.RegisterClassCommandBinding(
typeof(LooklessControl),
new CommandBinding(NextItemCommand, ExecutedNextItemCommand, CanExecuteNextItemCommand));
CommandManager.RegisterClassCommandBinding(
typeof(LooklessControl),
new CommandBinding(PrevItemCommand, ExecutedPrevItemCommand, CanExecutePrevItemCommand));
}
执行类命令绑定的原因是,如果将其添加到控件的CommandBindings集合中,使用控件的人可能会无意中删除它们。还记得更新命令处理方法,使其具有静态语义。+1用于按钮。滚动条也是这样做的。看,我同意,按钮的想法似乎是最好的途径。当我按照上面的建议连接它们时,我得到了一个不再点击的按钮。当我删除Command属性时,按钮会单击(但显然不会执行任何操作),当我将Command属性重新放入时,如下所示:
static LooklessControl()
{
CommandManager.RegisterClassCommandBinding(
typeof(LooklessControl),
new CommandBinding(NextItemCommand, ExecutedNextItemCommand, CanExecuteNextItemCommand));
CommandManager.RegisterClassCommandBinding(
typeof(LooklessControl),
new CommandBinding(PrevItemCommand, ExecutedPrevItemCommand, CanExecutePrevItemCommand));
}