WPF Calendar megjelenítési probléma

WPF Calendar megjelenítési probléma
2015-05-25T08:51:08+02:00
2015-05-26T15:15:53+02:00
2022-10-15T23:15:57+02:00
padro
Sziasztok!

Egy Calendar-ban kiválasztott dátumot (év, hó) szeretnék megjeleníteni egy TextBox-ban. Ezt a cikket próbáltam segítségül hívni. Sajnos, amint a DataContext-et beállítom, a Calendar használhatatlan lesz, azaz eltűnik a tartalma és összesen egy klikket engedélyez. Ha comment-be rakom a DataContext-et, akkor látszik minden, csak éppen nem tudok tovább lépni az MVVM felé.
XAML:


<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="20"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300*" MinWidth="80"/> <ColumnDefinition Width="auto" MinWidth="50"/>
</Grid.ColumnDefinitions>
<Slider x:Name="zoom" Orientation="Horizontal" Minimum="0.5" Maximum="3" Value="1" Grid.Column="1" Grid.Row="0"/>
<DockPanel Grid.Row="1" Grid.Column="0">
<DockPanel.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=zoom, Path=Value}" ScaleY="{Binding ElementName=zoom, Path=Value}"/>
</DockPanel.LayoutTransform>
<Viewbox DockPanel.Dock="Top" Height="160" MaxHeight="210" Width="160" MaxWidth="210" HorizontalAlignment="Left">
<Calendar Name="calendar1" DisplayMode="Year" Height="150" MaxHeight="200" Width="170" MaxWidth="200" Margin="1"
DisplayModeChanged="_Calendar_DisplayModeChanged" DisplayDateChanged="_Calendar_DisplayDateChanged" PreviewMouseUp="_Calendar_PreviewMouseUp"
DisplayDateStart="2014.01.01">
</Calendar>
</Viewbox>
<TreeView Name="tv" DockPanel.Dock="Left" ItemsSource="{Binding}" >
...
</TreeView>
</DockPanel>
<TextBox Name="DatumText" Grid.Column="0" Grid.Row="0" Width="100" Height="20" Text="{Binding TextValue}"/>
</Grid>



public partial class MainWindow : Window {


private void _Calendar_DisplayModeChanged(Object InSender, CalendarModeChangedEventArgs InE)
{
if (calendar1.DisplayMode != CalendarMode.Year)
calendar1.DisplayMode = CalendarMode.Year;
}
private void _Calendar_DisplayDateChanged(Object sender, CalendarDateChangedEventArgs InE)
{
var calend = sender as Calendar;
DateTime? date = calend.DisplayDate;
if (date == null)
this.Title = "No date";
else
TextValue = date.Value.ToShortDateString();
 //this.Title = date.Value.ToShortDateString(); ----- A form title szépen felveszi a dátumértéket, ha ez a sor él
}
private void _Calendar_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (Mouse.Captured is CalendarItem)
Mouse.Capture(null);
}


public string TextValue { get; set; }
public MainWindow()
{
InitializeComponent();
TextValue = "2015. 05.";
DataContext = this; //amint ez bekerül, elromlik a Calendar
}

Elnézést, ha túl kusza lett a forrás beszúrás. Régebben nem kellett ennyit küszködnöm vele.

Win7; Visual Studio 2013; C#; WPF

Ez szörnyű lett. A post előtt még tele volt TAB-okkal
Mutasd a teljes hozzászólást!
Helló!

Konkrét problémádra a válasz, hogy töröld ki a DisplayMode="Year"-t a XAML-ból (feltehetően ez egy bug).

Ha egyszerűen ki akarod írni a kiválasztott dátumot, azt közvetlenül kötheted a Calendar vezérlő property-jére:

<TextBox Name="DatumText" Grid.Column="0" Grid.Row="0" Width="100" Height="20" Text="{Binding ElementName=calendar1, Path=SelectedDate}"/>
---

Ha már itt vagyunk, sajnos Dante kolléga nem folytatta az egyébként kitűnő tutorial-ját, így muszáj máshol továbblépned.

Optimális esetben a XAML view-k code behind-jába nem kéne írni semmit (te ott kezeled a Calendar eseményeit). Pont ez az MVVM egyik fő lényege, hogy teljesen elválasztjuk a kódot az UI-tól így függetlenül lehet a kinézetet a működéstől változtatni. Ha eseményeket code behind-ban kezelsz és nem ICommand interface-en keresztül, property-k kötésével, akkor ez nem teljesül.

Ha nagyjából világos az alap MVVM koncepció, amit a blogon olvashattál, célszerű továbblépni és valamilyen MVVM keretrendszert használni. Egy ilyen az MVVM Light, NuGet-ből telepíthető. Itt találsz egy tutorial-t, hogy kell használni.

Az MVVM Light segítségével nemcsak jól megírt alaposztályokat kapsz, hanem egyéb olyan segédosztályokat, amelyek segítenek a tipikus problémákon, a te esetedben pl. azon, hogyan lehet a Calendar eseményeit átalakítani ICommand property-kre.
Mutasd a teljes hozzászólást!

  • Köszönöm!
    A Calendar-hoz így tényleg hozzá tudtam kötni a TextBox-ot, csak a megjelenítés nem olyan, amit elképzeltem. Jó lett volna a havi szintű kiválasztás, mert így nem kéne a felhasználónak magyarázni, hogy miért kell a hónapon belül napot is kiválasztania egy havi riporthoz. A DatePicker (nekem)  nem szimpatikus.
    Működik egyébként úgy is, hogy induláskor Year a DisplayMode, csak a kiiktatott eseménykezelők miatt át is vált Month-ra.
    Az útmutatást és a linket is köszönöm. Már több hozzászólásod (és a WPF-es kemény magé is) értékes volt számomra.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd