私は自分でWPFを学習しようとしていますが、それは少し苦労しています。バインドを介して、添付プロパティの値を設定する方法を知る必要があります。添付プロパティGrid.RowおよびGrid.RowSpanは、バインディングのソースではなく、の宛先です。 StackOverflowについても同様の質問がありましたが、WPFを本当に知っている人が尋ねて回答したり、バリューコンバータのような複雑な問題を抱えていました。私は適用可能で、わかりやすい答えを見つけられませんでした。添付プロパティをバインドする方法
この場合、1日のスケジュールを表すグリッドがあり、イベントを追加したいと思います。各イベントは、イベントの開始時刻と期間に応じて、特定のグリッド行から開始し、複数の行にまたがります。私の理解では、バインディングのソースとして依存関係プロパティを使用する必要があるので、イベントオブジェクトActivityBlock
には、グリッド上の位置を表すためのStartIncrement
およびDurationIncrements
依存プロパティがあります。
それだけです、私がやりたいことです。つまり、バインディングを使ってグリッド内にUserControlの位置を設定します。
MainWindow XAMLで問題が発生している可能性が高いですが、グリッドにバインディングが正しく設定されていません。 (私は、コンストラクタでプログラムでグリッド行を作成するので、以下のXAMLでそれらを検索しないでください)。
アプリケーションを実行すると、イベントが作成されますが、Grid.RowとGrid.RowSpanが決して更新されないように、グリッドの適切な場所に表示されません。バインディングGrid.RowとGrid.RowSpanは不可能ですか?そうでない場合、私は何を間違っているのですか?ここで
は私の問題がある可能性が最も高いMainWindow.xaml、次のとおりです。ここで
<Window x:Class="DayCalendar.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DayCalendar"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Activated="Window_Activated"
>
<DockPanel LastChildFill="True">
<Rectangle Width="50" DockPanel.Dock="Left"/>
<Rectangle Width="50" DockPanel.Dock="Right"/>
<Grid x:Name="TheDay" Background="#EEE">
<ItemsControl ItemsSource="{Binding Path=Children}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding Path=StartIncrement}" />
<Setter Property="Grid.RowSpan" Value="{Binding Path=DurationIncrements}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</DockPanel>
</Window>
は、コードビハインドファイルメインウィンドウのためである:ここで
using System;
using System.Windows;
using System.Windows.Controls;
using DayCalendar.MyControls;
namespace DayCalendar {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
var rowDefs = TheDay.RowDefinitions;
rowDefs.Clear();
for (int ix = 0; ix < (60/ActivityBlock.MINUTES_PER_INCREMENT) * 24; ix += 1) {
rowDefs.Add(new RowDefinition());
}
}
private void Window_Activated(object sender, EventArgs e) {
if (m_firstActivation) {
m_firstActivation = false;
var firstActivity = new ActivityBlock();
var today = DateTime.Now.Date;
var startTime = today.AddHours(11.5);
var durationSpan = new TimeSpan(1, 0, 0);
firstActivity.SetTimeSpan(startTime, durationSpan);
TheDay.Children.Add(firstActivity);
}
}
private bool m_firstActivation = true;
}
}
はActivityBlockコードです:
using System;
using System.Windows;
using System.Windows.Controls;
namespace DayCalendar.MyControls {
public partial class ActivityBlock : UserControl {
public int StartIncrement {
get { return (int) GetValue(StartIncrementProperty); }
set { SetValue(StartIncrementProperty, value); }
}
public int DurationIncrements {
get { return (int) GetValue(DurationIncrementsProperty); }
set { SetValue(DurationIncrementsProperty, value); }
}
public ActivityBlock() {
InitializeComponent();
}
public void SetTimeSpan(DateTime startTime, TimeSpan duration) {
int startMinute = startTime.Hour * 60 + startTime.Minute;
int durationMinutes = (int) duration.TotalMinutes;
StartIncrement = startMinute/MINUTES_PER_INCREMENT;
DurationIncrements = Math.Max(1, durationMinutes/MINUTES_PER_INCREMENT);
}
static ActivityBlock() {
var thisType = typeof(ActivityBlock);
var affectsArrangeAndMeasure = FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure;
int startIncrementDefault = 0;
StartIncrementProperty = DependencyProperty.Register(
nameof(StartIncrement),
startIncrementDefault.GetType(),
thisType,
new FrameworkPropertyMetadata(startIncrementDefault, affectsArrangeAndMeasure)
);
int durationIncrementsDefault = 1;
DurationIncrementsProperty = DependencyProperty.Register(
nameof(DurationIncrements),
durationIncrementsDefault.GetType(),
thisType,
new FrameworkPropertyMetadata(startIncrementDefault, affectsArrangeAndMeasure)
);
}
public const int MINUTES_PER_INCREMENT = 6; // 1/10th of an hour
static public readonly DependencyProperty StartIncrementProperty;
static public readonly DependencyProperty DurationIncrementsProperty;
}
}
対応するXAMLは興味深いわけではありませんが、必要に応じて含めることができます:
<UserControl x:Class="DayCalendar.MyControls.ActivityBlock"
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:local="clr-namespace:DayCalendar.MyControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border BorderThickness="3" BorderBrush="Black" Background="Chartreuse">
<DockPanel LastChildFill="True">
<TextBlock TextWrapping="WrapWithOverflow">Event Description</TextBlock>
</DockPanel>
</Border>
</UserControl>
私はあなたが達成したいことについて曖昧な手がかりを持っています。しかし、CodeBehindとxamlを混ぜることは難しく、実現することは不可能です。一つ自分自身に尋ねなさい。私はCodeBehindで**すべて**を行い、私が望むすべてのコントロールにアクセスできるようにするか、またはMVBMに切り替える必要があります。これは、DataBindingが意味をなさないためです。 – lokusking