WPF 优化 XAML 代码 [英] WPF Optimize XAML code
问题描述
是否有更有效的方式来编写 XAML 代码?(当我说更高效时,我的意思是减少重复).特别是超链接和扩展器.谢谢!
Is there a more efficient way of writing following XAML code? (when I say more efficient i meant less repetitive). Especialy with the Hyperlinks and the Expanders. Thank you!
<Window x:Class="InterfazOhmio.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Background>
<ImageBrush ImageSource="Imagenes/background.jpg"></ImageBrush>
</Window.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</Style>
</ListBox.Resources>
<ListBox.Template>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<Expander Margin="2" Background="OliveDrab">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Source="Iconos/Pedidos.png" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Pedidos" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="Nuevo Pedido"/>
</Hyperlink>
</Label>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="Consultar Pedidos" />
</Hyperlink>
</Label>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="Pedidos Pendientes" />
</Hyperlink>
</Label>
</WrapPanel>
</Expander>
<Expander Margin="2" Background="OrangeRed">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Source="Iconos/Remitos.png" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Remitos" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="Nuevo Remito"/>
</Hyperlink>
</Label>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="Consultar Remitos" />
</Hyperlink>
</Label>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="Remitos Pendientes" />
</Hyperlink>
</Label>
</WrapPanel>
</Expander>
<Expander Margin="2" Background="Teal">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Source="Iconos/Facturas.png" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Facturas" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<StackPanel>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="Nueva Factura"/>
</Hyperlink>
</Label>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="Consultar Facturas" />
</Hyperlink>
</Label>
</StackPanel>
</Expander>
</ListBox>
</Grid>
</Window>
更新
好的,我尝试了建议的解决方案并且它起作用了,但是结果中存在一些小的视觉差异,如当时的图片所示:
Ok, i try suggested solution and it work, but there are some small visual differences in the result as can be seen on the then pictures:
左侧是原始菜单.右侧是带有 viewModel 的新模型:
On the left the original menú. On the right the new one with the viewModel:
- 选择项目被标记,而不是在原始菜单中.
- 扩展器的宽度太短
这是 XAML 的结果:
This is the result XAML:
<Window x:Class="InterfazOhmio.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:InterfazOhmio"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Window.Background>
<ImageBrush ImageSource="Imagenes/background.jpg"></ImageBrush>
</Window.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding myMenu}">
<ListBox.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</Style>
</ListBox.Resources>
<ListBox.Template>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<Expander Margin="2" Background="{Binding Color}">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Source="{Binding ImageSource}" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="{Binding Title}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<ListBox ItemsSource="{Binding Options}" Background="Transparent">
<ListBox.ItemTemplate>
<DataTemplate>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="{Binding}"/>
</Hyperlink>
</Label>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Expander>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
有人可以帮我吗?谢谢!更新二
Can anybody help me tih this? Thanks! UPDATE II
差点就搞定了!!!
XAML:
<Window x:Class="InterfazOhmio.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:InterfazOhmio"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Window.Background>
<ImageBrush ImageSource="Imagenes/background.jpg"></ImageBrush>
</Window.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding myMenu}">
<ItemsControl.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</Style>
</ItemsControl.Resources>
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<ItemsPresenter/>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander Margin="2" Width="196" Background="{Binding Color}">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Source="{Binding ImageSource}" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="{Binding Title}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<ItemsControl ItemsSource="{Binding Options}" Background="Transparent" BorderThickness="0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="{Binding}"/>
</Hyperlink>
</Label>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
我用 ItemsControl 替换了列表框.现在唯一不起作用的是一次只能扩展一个扩展器.我想问题是这段代码:
I replace the listbox with ItemsControl. The only thing that is not working now is that only one expander should by expanded at a time. I guess the problem is this code:
<ItemsControl.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</Style>
</ItemsControl.Resources>
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<ItemsPresenter/>
</ControlTemplate>
</ItemsControl.Template>
因为它指向 ListBoxItem 类.问题是 ItemsControlItem 类不存在.是现在唯一的问题!!!
Because it points to ListBoxItem class. The problem is that ItemsControlItem class doens´t exist. Is the only problem right now!!!
推荐答案
可以使用 ViewModel 来完成,然后将 xaml 分解为单个项目作为模板:
It could be done with a ViewModel and then xaml is down to a single item as the template:
设置虚拟机的上下文
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
又快又脏的虚拟机和模型
quick and dirty VM and model
public class ViewModel
{
public ObservableCollection<Item> Items { get; set; }
public ViewModel()
{
Items = new ObservableCollection<Item>() { new Item() { Title="Pedidos", ImageSource="Iconos/Pedidos.png", Color=new SolidColorBrush(Colors.OliveDrab), Options = new List<string>(){"Nuevo Pedido","Consultar Pedidos","Pedidos Pendientes"} },
new Item() { Title="Remitos", ImageSource="Iconos/Remitos.png", Color=new SolidColorBrush(Colors.OrangeRed), Options = new List<string>(){"Nuevo Remito","Consultar Remitos","Remitos Pendientes"} },
new Item() { Title="Facturas", ImageSource="Iconos/Facturas.png", Color=new SolidColorBrush(Colors.Teal), Options = new List<string>(){"Nuevo Factura","Consultar Facturas"} } };
}
}
public class Item
{
public string Title { get; set; }
public List<string> Options { get; set; }
public SolidColorBrush Color { get; set; }
public string ImageSource { get; set; }
}
然后是 XAML...
and then the XAML...
物品来源
<ListBox ItemsSource="{Binding Items}">
项目模板
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander Margin="2" Width="196" Background="{Binding Color}">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Source="{Binding ImageSource}" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="{Binding Title}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<ItemsControl ItemsSource="{Binding Options}" Background="Transparent" BorderThickness="0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
<Hyperlink TextDecorations="None">
<TextBlock Foreground="White" Text="{Binding}"/>
</Hyperlink>
</Label>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
这篇关于WPF 优化 XAML 代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!