2010-03-23 120 views
1

顯示對象我很新的這個,我可以連詞組題吧......麻煩在WPF

無論如何,我試圖做一些事情非常簡單,一直摸不清出來。我有以下類:

public class Day : Control, INotifyPropertyChanged 
{ 
    public static readonly DependencyProperty DateProperty = 
     DependencyProperty.Register("Date", typeof(int), typeof(Day)); 

    public int Date 
    { 
     get { return (int)GetValue(DateProperty); } 
     set 
     { 
      SetValue(DateProperty, value); 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("Date")); 
      } 
     } 
    } 

    public static readonly DependencyProperty DayNameProperty = 
     DependencyProperty.Register("DayName", typeof(String), typeof(Day)); 

    public String DayName 
    { 
     get { return (String)GetValue(DayNameProperty); } 
     set 
     { 
      SetValue(DayNameProperty, value); 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("DayName")); 
      } 
     } 
    } 

    static Day() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(Day), new FrameworkPropertyMetadata(typeof(Day))); 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 

我瞭解到,你不能調用在XAML參數所以唯一的辦法實際設置一些數據,這個類是通過兩個屬性,DAYNAME和構造日期。

我創建了天一個控件模板是如下:

<Style TargetType="{x:Type con:Day}"> 
    <Setter Property="MinHeight" Value="20"/> 
    <Setter Property="MinWidth" Value="80"/> 
    <Setter Property="Height" Value="20"/> 
    <Setter Property="Width" Value="80"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type con:Day}"> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition/> 
         <ColumnDefinition/> 
        </Grid.ColumnDefinitions> 
        <Rectangle Grid.ColumnSpan="2" x:Name="rectHasEntry" Fill="WhiteSmoke"/>  
        <TextBlock Grid.Column="0" x:Name="textBlockDayName" Text="{TemplateBinding DayName}" FontFamily="Junction" FontSize="11" Background="Transparent" 
           HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,2,0,0"/> 
        <TextBlock Grid.Column="1" x:Name="textBlockDate" Text="{TemplateBinding Date}" FontFamily="Junction" FontSize="11" Background="Transparent" 
           HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,2,0,0"/> 
        <Rectangle Grid.ColumnSpan="2" x:Name="rectMouseOver" Fill="#A2C0DA" Opacity="0" 
           Style="{StaticResource DayRectangleMouseOverStyle}"/> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

我然後渲染它在屏幕上的我的主窗口正是如此:

<Window x:Class="WPFControlLibrary.TestHarness.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:con="clr-namespace:WPFControlLibrary.Calendar;assembly=WPFControlLibrary" 
    Title="MainWindow" Height="500" Width="525" 
    WindowStartupLocation="CenterScreen"> 
<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="80"/> 
    </Grid.ColumnDefinitions> 
    <con:Day Grid.Column="1" Height="20" Width="80" DayName="Mon" Date="1"/> 
</Grid> 

而我實際上看到的是,沒什麼。如果我將光標放在XAML的con:Day行上,它會突出顯示窗口中正確大小的矩形,但我沒有在矩形左側看到「Mon」,而在右側看到「1」。

我在做什麼錯?我懷疑這很簡單,但如果我看到它,我會感到厭煩。

我的最終目標是將一組日期控件分組在一個月份控件中,然後將其包含在年份控件中,因爲我正在嘗試製作一個長日曆欄,以便您瀏覽月份和年份,而點擊一天將顯示該日期保存的任何信息。但我甚至無法讓Day部分獨立於其他任何東西顯示,所以我離其餘的功能還有很長的路要走。任何幫助將不勝感激。

回答

2

首先,如果您有DependencyProperties,則不需要執行INotifyPropertyChanged。以下是綽綽有餘:

public int Date 
    { 
     get { return (int)GetValue(DateProperty); } 
     set { SetValue(DateProperty, value); } 
    } 

當我嘗試你的榜樣(無rectMouseOver,因爲我沒有的DayRectangleMouseOverStyle的定義),Mon顯示得很好,但1顯示不出來。我能夠有明確的結合取代TemplateBinding來解決這個問題:與其

{TemplateBinding Date} 

使用

{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Date} 

這種變化之後,你的代碼工作正常。我不知道爲什麼,但有時候TemplateBinding似乎「破碎」。

+0

仍然沒有運氣。我從Day類中刪除了INotifyPropertyChanged代碼,並將{TemplateBinding Date}(和DayName)更改爲{Binding RelativeSource = {RelativeSource TemplatedParent},Path = Date},但我仍然沒有看到任何東西。我已經在VS2008 Express和VS2010 RC中試過了,但沒有運氣。我也刪除了rectMouseOver Rectangle,以防止這種情況發生,但是什麼也沒做。 – Scott

+0

@Scott:奇怪。如果你想看看這裏有什麼作用,我已經上傳了我用來測試的項目:http://www.heinzi.at/temp/CsWpfApplication1.zip。我希望這可以幫助你調試什麼是錯誤的... – Heinzi

+0

啊哈,我現在看到它。我的樣式位於名爲Generic.xaml的資源字典中,而您的樣式位於MainWindow的Window.Resources中。當我將樣式移動到MainWindow時,它工作正常。顯然,我的對象沒有找到Generic.xaml中的樣式,因爲我認爲他們會通過TargetType屬性。顯然我對這個作品的理解是有缺陷的。因此,如果我在不同的資源字典中使用了我的樣式,那麼使用這些樣式的對象如何找到它們呢?我認爲這就是設置控制模板的TargetType的目的? – Scott

0

您需要爲您的類設置DataTemplate,而不是ControlTemplate。

DataTemplates用於定義如何顯示自定義類。 ControlTemplates(通過樣式)用於設置控件的風格。

有關詳細信息,我建議您閱讀Data Templating Overview on MSDN

0

你從一個只會給你帶來悲傷的角度來解決這個問題。我知道這一點,因爲我確實做了你想要做的一次。

考慮接近它是這樣的:你有一個Day類暴露DayNameDayNumberColumn性能。然後,您可以創建一個數據模板該類:

<DataTemplate DataType="{x:Type local:Day}"> 
    <TextBlock Grid.Column="{Binding Column}" 
       Text="{Binding DayNumber}" 
       ToolTip="{Binding DayName}"/> 
</DataTemplate> 

現在創建一個Week類,它包含Day對象的集合。該類創建模板:

​​

和包含Week對象的集合Month類。它的數據模板看起來是這樣的:

<DataTemplate> 
    <ItemsControl ItemsSource="{Binding Weeks}"/> 
</DataTemplate> 

(你並不需要在這裏創建一個ItemsPanelTemplate因爲模板ItemsPanel默認使用,垂直StackPanel,是一個你想要的

如果現在。您創建一個Month對象的實例(並正確填充其周和日),在WPF需要呈現它的XAML中的任何位置,它將創建一個包含若干Grid的垂直StackPanel,其中每個包含七個TextBlock,並帶有適當的一天中的數字

創建一個Year對象和它的模板我將作爲練習離開你。最後,您將爲這些模板添加ScrollViewer和樣式,並在對象模型中實現更多屬性以幫助實現UI。例如,如果您希望某一天顯示的信息有所不同,那麼您可以將HasInformation屬性添加到Day類,並實現數據觸發器以更改其背景顏色或字體權重。並且您將實現Command對象,用於您實際需要執行的操作,例如顯示特定日期的信息。你會到達那裏。