リストボックスにレンダリングされるユーザーコントロールにあるWPFエキスパンダーに問題があります。基本的に、リストボックス内の各ListItemでPopUpButtonの動作を取得しようとしています。エキスパンダーを開くと、コンテンツは透明であるかのように、またはzオーダーで低くなるように、他のすべての背後にレンダリングされます。WPFポップアップとトグルボタンでもこれを試しましたが(Karle Shivlletのブログ–ポップアップコンテンツを使用したエキスパンダーコントロールで説明されている手法を使用)、役に立ちませんでした。
まず、私がやろうとしていることについて説明しましょう。アプリケーション用に構成する必要のある入力のリストを表示する2つのコントロールがあります。簡単にするために、1つのユーザーコントロールを使用してグラフへの入力を構成し、別のコントロールを使用して単純なExcelグリッドへの入力を制御します。グラフとグリッドの入力にはそれぞれ、構成する必要のあるプロパティがあります。グラフまたはグリッド用に構成する入力のリストを含むListBoxをレンダリングするInputSelectControlと呼ばれる単純なユーザーコントロールを開発しました。ListBoxの各ListItemは、入力の名前(Pressure、ECGなど)のTextBlockと、クリックするとその入力のプロパティエディターを表示するWPFExpanderで構成されます。プロパティエディタの表示は、グラフ入力とグリッド入力のどちらを扱っているかによって異なるため、ControlTemplate型のInputSelectControlでDependencyPropertyを使用しました。これにより、グリッドとグラフがそれぞれ、入力プロパティの編集に必要なプレゼンテーションを提供できるようになります。また、この動作を必要とするグラフとグリッド以上のものがあることに注意してください。したがって、これをプレゼンテーション動作を動的に受信できるユーザーコントロールにしたいという要望があります。
エキスパンダーをプロパティエディターテンプレート内に配置しようとしました。また、さまざまな場所でZIndexを試してみましたが、常に同じ動作になり、エキスパンダーポップアップがリストのListItemsの後ろに表示されます。
以下は、私のアプローチをさらに説明するコードです。うまくいけば、誰かがこの漬物から私を助けることができます。
InputSelectControlを保持するグリッド(グラフなど)コントロールを表すXAML:
<UserControl x:Class="MyApp.GridView"
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"
xmlns:props="clr-namespace:PopupButtonDependencyProp" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<!-- Specify the control tempalte we want loaded into the
properies popup for a grid-->
<ControlTemplate x:Key="GridPropertyEditorTemplate" TargetType="ContentControl">
<props:GridInputPropertyEditor />
</ControlTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Hello Grid" Margin="5" />
<!-- Tell the InputSelectControl what template to load into Property
Window for each Grid Input item -->
<props:InputSelectControl Grid.Row="1"
DataContext="{Binding VmUsedInputs, Mode=OneWay}"
PropertyEditorTemplate="{StaticResource GridPropertyEditorTemplate}" />
</Grid>
</UserControl>
入力のリストを表示するInputSelectControlを表すXAMLと、プロパティを編集するための「Popupの動作」が必要な各ListItemのContentControlプレースホルダー:
<UserControl x:Class="MyApp.InputSelectControl"
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"
xmlns:props="clr-namespace:PopupButtonDependencyProp"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<!-- Listbox holding our inputs. Assuming whatever we're contained in has
set our DataContext to a valid Input collection-->
<ListBox x:Name="inputsUsed" Grid.Row="1" ItemsSource="{Binding}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SelectionMode="Multiple" ClipToBounds="True">
<ListBox.ItemTemplate>
<DataTemplate>
<Border x:Name="border" CornerRadius="7">
<StackPanel VerticalAlignment="Stretch" Orientation="Horizontal">
<!-- Input label-->
<TextBlock Text="{Binding Path=Label}" FontWeight ="Bold"
FontSize ="12" FontStyle = "Normal"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Margin="5,0,5,0" />
<Expander x:Name="GridPropEditor" Header="Properties"
Height="Auto" Margin="5,0,0,0"
ToolTip="Open trace property dialog">
<!-- Properties button - The ContentControl below is rendering
the PropertyEditorTemplate that was set by whoever contains us -->
<ContentControl Template="{Binding PropertyEditorTemplate,
RelativeSource={RelativeSource AncestorType=props:InputSelectControl}}" />
</Expander>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
ポップアップに表示するプロパティエディタテンプレートを挿入するためのDependencyPropertyを表すC#。
/// <summary>
/// Interaction logic for InputSelectControl.xaml
/// </summary>
public partial class InputSelectControl : UserControl
{
#region Dependency Property stuff
/// <summary>
/// Dependency Property for control template to be rendered. This
/// lets us adorn the InputSelectControl with content in the Xaml.
/// The content can be different fore each instance of InputSelectControl.
/// </summary>
public static DependencyProperty PropertyEditorTemplateProperty =
DependencyProperty.Register("PropertyEditorTemplate",
typeof(ControlTemplate), typeof(InputSelectControl));
/// <summary>
/// PropertyEditorTemplate. This is how the property is set and get by WPF
/// </summary>
public ControlTemplate PropertyEditorTemplate
{
get { return GetValue(PropertyEditorTemplateProperty) as ControlTemplate; }
set { SetValue(PropertyEditorTemplateProperty, value); }
}
#endregion
/// <summary>
/// Constructor
/// </summary>
public InputSelectControl()
{
InitializeComponent();
}
}
グリッドプロパティを編集するためのプレゼンテーションを説明するテンプレートであるGridInputPropertyEditorを表すXAML。これはグラフでは異なります。
<UserControl x:Class="MyApp.GridInputPropertyEditor"
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"
d:DesignHeight="300" d:DesignWidth="300">
<Canvas Panel.ZIndex=”99”>
<!-- Property Editor Control - Assumes DataContext holds to the properties
that need to be edited-->
<StackPanel Orientation="Vertical" Background="WhiteSmoke">
<!-- Lists the properties for a Grid to be edited. We could use
any layout we need here. -->
<ListBox ItemsSource="{Binding Properties}" Background="WhiteSmoke" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5,5">
<TextBlock Text="{Binding Label}" FontWeight="Bold"/>
<TextBlock Text=":" />
<TextBox Text="{Binding Value}" Margin="10,0" Width="20" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Canvas>
</UserControl>
Snoopを使用すると、ListBoxアイテムのZ-Indexを高い数値に設定すると、プロパティエディターが前面に表示されることがわかりました。誰かがこれを回避するより良い方法を見つけたら、私に知らせてください。それ以外の場合は、選択したアイテムに基づいてzindexを上下させるトリガーを考え出すのに役立つ可能性があります。