#c# #wpf #xaml
#c# #wpf #xaml
Вопрос:
Я просто хотел начать с того, что я видел похожие сообщения с той же проблемой, но они дают решение, не подходящее для моего сценария. Я создаю элемент управления разделением, как показано ниже. Проблема в том, что элемент управления имеет 3 области, в которых пользователи могут размещать любые элементы управления, которые они хотят, но эти элементы управления не могут быть названы с помощью этой ошибки:
Не удается установить значение атрибута Name ‘Item1’ для элемента ‘ListViewItem’. ‘ListViewItem’ находится в области элемента ‘SplitView’, у которого уже было зарегистрировано имя, когда оно было определено в другой области.
Как я могу это исправить? Я не хочу, чтобы при реализации этого элемента управления всегда приходилось добавлять некоторый код, чтобы обойти эту ошибку. Могу ли я добавить 3 области шаблонов в этот элемент управления, чтобы пользователь мог создать свой собственный шаблон с нужным контентом внутри каждой области. Как бы я это сделал? Я открыт для других идей.
Разметка
<UserControl x:Name="ThisControl" x:Class="ns.SplitView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Margin="10" Grid.Row="0" Grid.Column="0" x:Name="OpenPaneButton" Width="50" Height="50" Click="OpenPaneButton_Click" Background="{x:Null}" BorderBrush="{x:Null}" Focusable="False" >
<Viewbox>
<Canvas Width="300" Height="210">
<Path StrokeThickness="1" StrokeDashArray="" StrokeDashCap="Flat" StrokeDashOffset="0" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="10" Stroke="{Binding HamburgerButtonColor, ElementName=ThisControl}" Fill="{Binding HamburgerButtonColor, ElementName=ThisControl}">
<Path.Data>
<RectangleGeometry Rect="0,0,300,50" RadiusX="25" RadiusY="25" />
</Path.Data>
</Path>
<Path StrokeThickness="1" StrokeDashArray="" StrokeDashCap="Flat" StrokeDashOffset="0" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="10" Stroke="{Binding HamburgerButtonColor, ElementName=ThisControl}" Fill="{Binding HamburgerButtonColor, ElementName=ThisControl}">
<Path.Data>
<RectangleGeometry Rect="0,80,300,50" RadiusX="25" RadiusY="25" />
</Path.Data>
</Path>
<Path StrokeThickness="1" StrokeDashArray="" StrokeDashCap="Flat" StrokeDashOffset="0" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="10" Stroke="{Binding HamburgerButtonColor, ElementName=ThisControl}" Fill="{Binding HamburgerButtonColor, ElementName=ThisControl}">
<Path.Data>
<RectangleGeometry Rect="0,160,300,50" RadiusX="25" RadiusY="25" />
</Path.Data>
</Path>
</Canvas>
</Viewbox>
</Button>
<ContentPresenter x:Name="MainTitleContent" Panel.ZIndex="1" Content="{Binding TitleContent, ElementName=ThisControl}" Grid.Row="0" Grid.Column="1" Focusable="True"/>
<ContentPresenter x:Name="Pane" Panel.ZIndex="1" Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Width="0" HorizontalAlignment="Left" Content="{Binding PaneContent, ElementName=ThisControl}" LostFocus="Pane_LostFocus" LostMouseCapture="Pane_LostMouseCapture" LostKeyboardFocus="Pane_LostKeyboardFocus" LostTouchCapture="Pane_LostTouchCapture" LostStylusCapture="Pane_LostStylusCapture" Focusable="True"/>
<ContentPresenter x:Name="Content" Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="1" Content="{Binding MainContent, ElementName=ThisControl}" Focusable="True"/>
</Grid>
</UserControl>
Код, лежащий в основе
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace ns
{
public partial class SplitView
{
/// <summary>
/// A simple state to know if the pane is open
/// </summary>
public bool PaneIsOpen
{
get { return (bool)GetValue(PaneIsOpenProperty); }
set { SetValue(PaneIsOpenProperty, value); }
}
public static readonly DependencyProperty PaneIsOpenProperty = DependencyProperty.Register("PaneIsOpen", typeof(bool), typeof(SplitView));
public SolidColorBrush HamburgerButtonColor
{
get { return (SolidColorBrush)GetValue(HamburgerButtonColorProperty); }
set { SetValue(HamburgerButtonColorProperty, value); }
}
public static readonly DependencyProperty HamburgerButtonColorProperty = DependencyProperty.Register("HamburgerButtonColor", typeof(SolidColorBrush), typeof(SplitView), new UIPropertyMetadata(new SolidColorBrush(Colors.Black)));
public double PaneWidth
{
get { return (double)GetValue(PaneWidthProperty); }
set { SetValue(PaneWidthProperty, value); }
}
public static readonly DependencyProperty PaneWidthProperty = DependencyProperty.Register("PaneWidth", typeof(double), typeof(SplitView), new PropertyMetadata(null));
public object MainContent
{
get { return GetValue(MainContentProperty); }
set { SetValue(MainContentProperty, value); }
}
public static readonly DependencyProperty MainContentProperty = DependencyProperty.Register("MainContent", typeof(object), typeof(SplitView), new PropertyMetadata(null));
public object PaneContent
{
get { return GetValue(PaneContentProperty); }
set { SetValue(PaneContentProperty, value); }
}
public static readonly DependencyProperty PaneContentProperty = DependencyProperty.Register("PaneContent", typeof(object), typeof(SplitView), new PropertyMetadata(null));
public object TitleContent
{
get { return GetValue(TitleContentProperty); }
set { SetValue(TitleContentProperty, value); }
}
public static readonly DependencyProperty TitleContentProperty = DependencyProperty.Register("TitleContent", typeof(object), typeof(SplitView), new PropertyMetadata(null));
private readonly Duration PaneAnimationDuration = new Duration(new TimeSpan());
private DoubleAnimation ClosePaneAnimation => new DoubleAnimation {Duration = PaneAnimationDuration, To = 0, From = PaneWidth };
private DoubleAnimation OpenPaneAnimation => new DoubleAnimation {Duration = PaneAnimationDuration, To = PaneWidth, From = 0 };
public SplitView()
{
InitializeComponent();
}
private void OpenPaneButton_Click(object sender, RoutedEventArgs e)
{
PaneIsOpen = !PaneIsOpen;
//Debug.WriteLine($"pane is open: {PaneIsOpen}");
if (PaneIsOpen)
{
Pane.BeginAnimation(WidthProperty, OpenPaneAnimation);
Pane.Focus();
}
else
{
Pane.BeginAnimation(WidthProperty, ClosePaneAnimation);
}
}
private void Pane_LostFocus(object sender, RoutedEventArgs e)
{
PaneLostFocus();
e.Handled = true;
}
private void Pane_LostMouseCapture(object sender, MouseEventArgs e)
{
PaneLostFocus();
e.Handled = true;
}
private void PaneLostFocus()
{
if (PaneIsOpen)
{
PaneIsOpen = false;
Pane.BeginAnimation(WidthProperty, ClosePaneAnimation);
}
}
private void Pane_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
PaneLostFocus();
e.Handled = true;
}
private void Pane_LostTouchCapture(object sender, TouchEventArgs e)
{
PaneLostFocus();
e.Handled = true;
}
private void Pane_LostStylusCapture(object sender, StylusEventArgs e)
{
PaneLostFocus();
e.Handled = true;
}
}
}
Реализация
<customControls:SplitView x:Name="SplitView" PaneWidth="250" HamburgerButtonColor="{StaticResource AccentColorBrush2}">
<customControls:SplitView.MainContent>
<Grid>
</Grid>
</customControls:SplitView.MainContent>
<customControls:SplitView.PaneContent>
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="Navigation" Style="{StaticResource Header1}" Margin="10,5,5,5"/>
<!-- I can't name controls in these content areas -->
<ListView Grid.Row="1" BorderThickness="0" SelectionChanged="PaneItemsListView_SelectionChanged">
<ListViewItem x:Name="Item1" Style="{StaticResource SplitViewItemsStyle}" ">
<TextBlock Text="Project Explorer" Margin="20,5,10,5"/>
</ListViewItem>
<ListViewItem Style="{StaticResource SplitViewItemsStyle}" Tag="FieldServicesItem">
<TextBlock Text="Field Services" Margin="20,5,10,5"/>
</ListViewItem>
<ListViewItem Style="{StaticResource SplitViewItemsStyle}" Tag="ReportManagerItem">
<TextBlock Text="Report Manager" Margin="20,5,10,5"/>
</ListViewItem>
</ListView>
</Grid>
</customControls:SplitView.PaneContent>
<customControls:SplitView.TitleContent>
<Grid>
<TextBlock HorizontalAlignment="Center" Text="Current View" VerticalAlignment="Center" Style="{StaticResource Header1}"/>
</Grid>
</customControls:SplitView.TitleContent>
</customControls:SplitView>