2013-10-20 55 views
2

我正在編寫一個調度工具,我希望有一個類似於「日」的視圖,這在許多日曆應用程序中可用。選擇與畫布作爲ItemsPanelTemplate的綁定列表框項目

它作爲一個ListBox完成,因此用戶可以選擇一些事件。當我嘗試綁定事件時發生問題 - 選擇無法按預期工作。通過這個,我的意思是它看起來像拉伸到容器的頂部,再加上單擊事件不會在元素上處理,而是在元素和容器頂部邊緣之間的空間上處理。

下面是一個例子:在左側 - 它應該如何工作和看,這是通過手動放置兩個ListBoxItems來完成的。在右側,使用綁定。

enter image description hereenter image description here

我比較了這兩種情況下使用WPF調試工具的視覺樹和有在例如小的差異ContentPresenter東西,但我不明白到底發生了什麼,爲什麼會出現差異,以及如何刪除它。

這是我的XAML:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="PLA1.MainWindow" 
    x:Name="Window" 
    xmlns:local="clr-namespace:PLA1" 
    Title="MainWindow" 
    Width="640" Height="480"> 

    <Window.Resources> 
     <local:MarginConverter x:Key="marginConverter"/> 
    </Window.Resources> 

    <Grid x:Name="LayoutRoot"> 
     <ListBox Margin="8,8,0,8" Background="#C9BBC0FF" HorizontalAlignment="Left" Width="160"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <Canvas /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <ListBoxItem Margin="{Binding Path=StartMinutes, Converter={StaticResource marginConverter}}" Height="{Binding Path=Duration}" Width="150" Background="#8000FF00" Foreground="White" BorderThickness="2" BorderBrush="#80000000"> 
         <StackPanel> 
          <TextBlock Text="{Binding Path=Name}" Margin="5,0,0,0" Width="130" TextWrapping="Wrap" FontWeight="Bold" FontSize="18" /> 
          <TextBlock Text="{Binding Path=Place}" Margin="8,0,0,0" FontSize="14"/> 
         </StackPanel> 
        </ListBoxItem> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
      <ListBox.Effect> 
       <DropShadowEffect Opacity="0.625"/> 
      </ListBox.Effect> 

      <!-- uncomment these two lines to test binding --> 
      <!--local:Event Duration="200" StartMinutes="60" Name="Sprawdzian" Place="EA32" /> 
      <local:Event Duration="120" StartMinutes="300" Name="Oddanie projektu" Place="308" /--> 

      <ListBoxItem Margin="0,60,0,0" Height="200" Width="150" Background="#8000FF00" Foreground="White" BorderThickness="2" BorderBrush="#80000000"> 
       <StackPanel> 
        <TextBlock Text="Sprawdzian" Margin="5,0,0,0" Width="130" TextWrapping="Wrap" FontWeight="Bold" FontSize="18" /> 
        <TextBlock Text="EA32" Margin="8,0,0,0" FontSize="14"/> 
       </StackPanel> 
      </ListBoxItem>  

      <ListBoxItem Margin="0,300,0,0" Height="120" Width="150" Background="#8000FF00" Foreground="White" BorderThickness="2" BorderBrush="#80000000"> 
       <StackPanel> 
        <TextBlock Text="Oddanie projektu" Margin="5,0,0,0" Width="130" TextWrapping="Wrap" FontWeight="Bold" FontSize="18" /> 
        <TextBlock Text="308" Margin="8,0,0,0" FontSize="14"/> 
       </StackPanel> 
      </ListBoxItem> 
     </ListBox> 
    </Grid> 
</Window> 

事件類:

public class Event 
{ 
    public int StartMinutes { get;set; } 
    public int Duration { get; set; } 
    public string Name { get; set; } 
    public string Place { get; set; } 

    public Event() { } 
} 

MarginConverter類:

public class MarginConverter : IValueConverter 
{ 
    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return new Thickness(0, (int)(value), 0, 0); 
    } 

    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return null; 
    } 
} 

回答

1

您應該添加樣式,您可以設置相應屬性ListBoxItemListBox資源,改變ItemTemplate

<ListBox Margin="8,8,0,8" Background="#C9BBC0FF" HorizontalAlignment="Left" Width="160"> 
    <ListBox.Resources>     
     <Style TargetType="ListBoxItem"> 
      <Setter Property="Margin" Value="{Binding Path=StartMinutes, Converter={StaticResource marginConverter}}" /> 
      <Setter Property="Height" Value="{Binding Path=Duration}" /> 
      <Setter Property="Foreground" Value="White" /> 
      <Setter Property="BorderThickness" Value="2" /> 
      <Setter Property="BorderBrush" Value="#80000000" /> 
      <Setter Property="Width" Value="150" /> 
      <Setter Property="Background" Value="#8000FF00" /> 
     </Style> 
    </ListBox.Resources> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ListBox.ItemTemplate> 
     <DataTemplate>      
       <StackPanel> 
        <TextBlock Text="{Binding Path=Name}" Margin="5,0,0,0" Width="130" TextWrapping="Wrap" FontWeight="Bold" FontSize="18" /> 
        <TextBlock Text="{Binding Path=Place}" Margin="8,0,0,0" FontSize="14"/> 
       </StackPanel>       
     </DataTemplate> 
    </ListBox.ItemTemplate> 
    <ListBox.Effect> 
     <DropShadowEffect Opacity="0.625"/> 
    </ListBox.Effect> 

    <!-- uncomment these two lines to test binding --> 
    <local:Event Duration="200" StartMinutes="60" Name="Sprawdzian" Place="EA32" /> 
    <local:Event Duration="120" StartMinutes="300" Name="Oddanie projektu" Place="308" /> 

    <!--<ListBoxItem Margin="0,60,0,0" Height="200" Width="150" Background="#8000FF00" Foreground="White" BorderThickness="2" BorderBrush="#80000000"> 
     <StackPanel> 
      <TextBlock Text="Sprawdzian" Margin="5,0,0,0" Width="130" TextWrapping="Wrap" FontWeight="Bold" FontSize="18" /> 
      <TextBlock Text="EA32" Margin="8,0,0,0" FontSize="14"/> 
     </StackPanel> 
    </ListBoxItem> 

    <ListBoxItem Margin="0,300,0,0" Height="120" Width="150" Background="#8000FF00" Foreground="White" BorderThickness="2" BorderBrush="#80000000"> 
     <StackPanel> 
      <TextBlock Text="Oddanie projektu" Margin="5,0,0,0" Width="130" TextWrapping="Wrap" FontWeight="Bold" FontSize="18" /> 
      <TextBlock Text="308" Margin="8,0,0,0" FontSize="14"/> 
     </StackPanel> 
    </ListBoxItem>--> 
</ListBox> 

視覺樹有兩個ListBoxItem項目:

enter image description here

在這例如一切正常,HeightMargin屬性在代碼中設置。

視覺樹有兩個Event項目:

enter image description here

在你定義ItemTemplateListBoxItem但默認情況下ListBox也將增加容器ListBoxItem這個例子,所以你有兩個ListBoxItem的,這裏是問題,因爲你只爲內部ListBoxItem設置高度和邊距。外ListBoxItem具有默認屬性。

如果你想自己檢查一下,你可以使用這個snoop(http://snoopwpf.codeplex.com/)。

+0

工程就像一個魅力,謝謝!所以這意味着綁定機制將我的** Event **對象包裝在ListBoxItems中,我們不應該明確地做。 – PiotrK

+0

@PiotrK再次檢查我的答案,我添加了一些解釋。我希望現在更清楚。 – kmatyaszek

0

嘗試如下更新列表框:

<ListBox Margin="8,8,0,8" Background="#C9BBC0FF" HorizontalAlignment="Left" Width="160"> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel/> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
     <ListBox.ItemContainerStyle> 
      <Style TargetType="ListBoxItem"> 
        <Setter Property="Height" Value="{Binding Duration}"/> 
        <Setter Property="Margin" Value="{Binding Path=StartMinutes, Converter={StaticResource marginConverter}}" /> 
      </Style> 
     </ListBox.ItemContainerStyle> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
        <StackPanel Background="#8000FF00" BorderThickness="2" BorderBrush="#80000000"> 
         <TextBlock Text="{Binding Path=Name}" Margin="5,0,0,0" Width="130" TextWrapping="Wrap" FontWeight="Bold" FontSize="18" /> 
         <TextBlock Text="{Binding Path=Place}" Margin="8,0,0,0" FontSize="14"/> 
        </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
相關問題