まず、すべてのXAMLについて申し訳ありません。私はこれを解決するために数日間試しましたが、私は何かが欠けているに違いありません。要約すると、私のUserControl
依存関係プロパティは、コードビハインドが使用されているときにデータバインドに現れません。単純なUserControlでデータバインディングが失敗する
詳細:私は秒を選択することが0..59からスライダーを使用しています、とUserControl
がで構成されるTimeSpan
を返し依存関係プロパティValue
を持って次のような単純なUserControl
(独自のDLL内)を、持っていますスライダーを介して、選択秒:
public partial class TinyTimeSpanControl : UserControl, INotifyPropertyChanged
{
public TinyTimeSpanControl()
{
InitializeComponent();
}
private int _seconds;
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public int Seconds
{
get { return _seconds; }
set
{
if (_seconds == value)
return;
_seconds = value;
RaisePropertyChanged("Seconds");
var t = Value;
Value = new TimeSpan(t.Hours, t.Minutes, _seconds);
}
}
public TimeSpan Value
{
get { return (TimeSpan) GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
TinyTimeSpanControl control = obj as TinyTimeSpanControl;
var newValue = (TimeSpan)e.NewValue;
control.Seconds = newValue.Seconds;
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(TimeSpan), typeof(TinyTimeSpanControl), new PropertyMetadata(OnValueChanged));
}
シンプル(省略さ)XAMLの場合:
<UserControl x:Class="WpfControlLibrary1.TinyTimeSpanControl" x:Name="root">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Slider Name="SecondsSlider"
Width="120"
Height="23"
HorizontalAlignment="Left"
VerticalAlignment="Top"
LargeChange="5"
SelectionStart="0"
SmallChange="1"
Value="{Binding Path=Seconds,
ElementName=root}" SelectionEnd="59" Maximum="59" />
<Label Name="label1"
Grid.Column="1"
Content="{Binding ElementName=SecondsSlider,
Path=Value}" />
<Label Name="label2"
Grid.Column="2"
Content="Seconds" />
</Grid>
</UserControl>
コントロールにバインドすると、正常に動作します。
今、私はこれをコンパイルするときは、(省略さ)私の窓の一つにTinyTimeSpanControl
を追加します。
<Window x:Class="WpfControls.MainWindow"
xmlns:my="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
x:Name="root"
Closing="root_Closing">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="142*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<my:TinyTimeSpanControl Name="tinyTimeSpanControl1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Value="{Binding ElementName=root,
Path=TheTime}" />
<Label Name="label1"
Grid.Column="1"
Content="{Binding ElementName=tinyTimeSpanControl1,
Path=Value}" />
<Label Name="label2"
Grid.Column="2"
Content="{Binding ElementName=root,
Path=TheTime}" />
</Grid>
</Window>
私のメインウィンドウ:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private TimeSpan _theTime = new TimeSpan(0, 0, 33);
public TimeSpan TheTime
{
get
{
return _theTime;
}
set
{
if (_theTime == value)
return;
_theTime = value;
RaisePropertyChanged("TheTime");
}
}
データバインディングは、部分的に動作します:
tinyTimeSpanControl1
は、最初にTheTime
の値に設定されています。私のメインウィンドウの背後にあるコードtinyTimeSpanControl1
label1
スライダを動かすと。
しかし、動作しません:
- スライダーが移動し、
label2
が残っWindow_closing
イベントの中でブレークポイントを置くTheTime
の元のバージョンに設定がTheTime
していないことを示していますかわった。
私はUserControl
に提起する必要があるいくつかのイベントがありませんか?
すべてのxamlについてもう一度お詫び申し上げます(これは最小のケースでもあります)。
あなたのコードは*本当に*混乱、すべての最初で、ラベルは、(単純なテキスト表示のためではなく、入力コントロールにラベルを付けます彼らはアクセステキストサポートを持っていて、 'Target'プロパティを使ってinput要素を参照します)、代わりに' TextBlocks'を使います。次に、バインドされたテキストの横に静的なテキストを表示したい場合は、それを追加するために 'Binding.StringFormat'を使うことができます。 –
私はハードコードされたイベントの使用を避けるためにINPCを使用しています。なぜなら、予想よりも少し複雑に見えるかもしれないからです。 – Barry