3

(DP の構文エラーを修正するために編集 - 問題は解決しません)

単純なカスタム ユーザー コントロール内の依存関係プロパティへのデータ バインディングで問題が発生しています。

基本的に、ユーザーコントロール内にはラベルと 2 つのボタンがあります。ラベルは依存関係プロパティにバインドされており、ボタンをクリックすると、ボタンのクリックに応じてカウントが増減し、ラベルによって表示されます。

ユーザーコントロールなしでページ内でこれをすべて行うと、すべて正しく機能します。ただし、ユーザーコントロールに移動すると、奇妙な動作を開始します。期待どおり、開始時に初期カウント 0 が表示され、ボタンをクリックすると、最初のクリックで改訂されたカウントが表示されます。ただし、同じボタンをもう一度クリックすると、依存関係プロパティは更新されますが、値は表示されません (ラベルが空白になります)。ただし、他のボタンをクリックすると、修正されたカウントが表示されますが、最初のクリックだけです-それはすべて非常に奇妙で、行き詰まっています!

「TheCountProperty_Changed」メソッドにブレークポイントを設定すると、プロパティ値が正しく更新されていることを確認できます..

カスタム コントロールの XAML は次のとおりです。

<UserControl
x:Class="DPTest.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DPTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="TestControl"
x:Uid="TestControl">

<Grid>
    <TextBlock x:Name="lblCount" HorizontalAlignment="Left" Margin="0,0,0,0" TextWrapping="Wrap" Text="{Binding Path=TheCount, ElementName=TestControl, Mode=OneWay}" VerticalAlignment="Top" FontSize="36"/>
    <Button x:Name="btnLess" Content="&lt;" HorizontalAlignment="Left" Margin="0,71,0,0" VerticalAlignment="Top" Width="75" Click="btnLess_Click" ClickMode="Press"/>
    <Button x:Name="btnMore" Content="&gt;" HorizontalAlignment="Left" Margin="91,71,0,0" VerticalAlignment="Top" Width="75" Click="btnMore_Click" ClickMode="Press"/>

</Grid>

そして、これがそのCSです:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace DPTest
{
public sealed partial class UserControl1 : UserControl
{
    public static readonly DependencyProperty TheCountProperty = DependencyProperty.Register("TheCount", typeof(int), typeof(UserControl1), new PropertyMetadata(0, new PropertyChangedCallback(TheCountProperty_Changed)));

    public int TheCount
    {
        get { return (int)GetValue(TheCountProperty); }
        set { SetValue(TheCountProperty, value); }
    }
    private static void TheCountProperty_Changed(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {

    }

    public UserControl1()
    {
        this.InitializeComponent();
    }

    private void btnLess_Click(object sender, RoutedEventArgs e)
    {
        //lblCount.Text = (Convert.ToInt32(lblCount.Text) - 1).ToString();
        this.TheCount -= 1;
    }

    private void btnMore_Click(object sender, RoutedEventArgs e)
    {
        //lblCount.Text = (Convert.ToInt32(lblCount.Text) + 1).ToString();
        this.TheCount += 1;
    }
}
}

私のデータバインディング構文が少し間違っていると思いますが、どうすればよいですか?

(編集) - プロットが厚くなります!標準の WPF アプリケーションでまったく同じ構文を試したところ、すべてが期待どおりに機能することを付け加えたいと思います。問題は、WinRT/XAML でバグを見つけたのか、それともそのプラットフォームを使用すると構文が異なるのかということだと思います。

(編集#2すべての編集で申し訳ありませんが、私はまだこれを解決しようとしています!)ボタンコントロールの表示の問題またはバグであると信じ始めています。追加のボタンを追加したばかりですが、クリックイベントコードなどを配線していません。基本的には何もしないボタンです。興味深い点は次のとおりです。

  • テスト アプリを起動して btnMore ボタンをクリックすると、TheCount がインクリメントされ、Textblock が期待どおりに更新されます。次に同じボタンをもう一度クリックすると、TheCount がインクリメントされますが、lblCount の Text 値は空の文字列になります。
  • ただし、テストアプリを起動して btnMore を押し、未使用のボタンを押してそれを繰り返すと、btnMore を 2 回続けて押さない限り、値は増加し続け、TextBlock は更新され続けますが、空白のボタンを押すと (または実際に空白のテキスト ボックスまたはその他の UI にカーソルを合わせると)、TextBlock は増加する数値を表示し続けます。btnMore を 2 回以上クリックすると、lblCount の値が空の文字列になります。

これは非常に怪しい……。

4

3 に答える 3

2

DependencyProperty の 3 番目の引数は、'UserControl' ではなく、'UserControl1' であるように見えます。

Win 8 をスピンアップして自分でコードを試してみたところ、あなたが抱えていたのと同じ問題が発生しました。

そこから、次の 2 つのことを判断できました。

1)依存関係プロパティは基本的に正しかった。ボタンがクリックされると、プロパティの値が増減するのを観察できました。これは、問題がある種の更新の問題であることを示していました。

2) コードを UserControl から Main xaml ページ (私のテスト アプリでは、デフォルトの 'Blank.xaml' ページでした) に移動すると、数値が適切に更新されました。

ベータ版にはある種のリフレッシュ バグ (エラー..「コンシューマー プレビュー」) があり、アプリケーションの構造を少し変えることで回避できるようです。

于 2012-03-18T19:57:52.360 に答える
1

これは、WinRT での同期の問題のようです。コンバーターを使用して取得内容を確認したところ、int 値が null に設定されているように見えました。プロパティへの更新を非同期的に呼び出すようにコードを変更すると、正常に動作し始めました。

XAML:

<UserControl
    x:Class="DPTest.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DPTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"
    x:Name="TestControl"
    x:Uid="TestControl">

    <Grid>
        <Grid.Resources>
            <local:IntToStringConverter
                x:Key="IntToStringConverter" />
        </Grid.Resources>
        <TextBlock
            x:Name="lblCount"
            HorizontalAlignment="Left"
            Margin="0,0,0,0"
            TextWrapping="Wrap"
            Text="{Binding Path=TheCount, Converter={StaticResource IntToStringConverter}, ElementName=TestControl, Mode=OneWay}"
            VerticalAlignment="Top"
            FontSize="36" />
        <Button
            x:Name="btnLess"
            Content="&lt;"
            HorizontalAlignment="Left"
            Margin="0,71,0,0"
            VerticalAlignment="Top"
            Width="75"
            Click="btnLess_Click"
            ClickMode="Release" />
        <Button
            x:Name="btnMore"
            Content="&gt;"
            HorizontalAlignment="Left"
            Margin="91,71,0,0"
            VerticalAlignment="Top"
            Width="75"
            Click="btnMore_Click"
            ClickMode="Release" />
    </Grid>
</UserControl>

コードビハインド:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace DPTest
{
    public sealed partial class UserControl1 : UserControl
    {
        public static readonly DependencyProperty TheCountProperty =
            DependencyProperty.Register(
                "TheCount",
                typeof(int),
                typeof(UserControl1),
                new PropertyMetadata(
                    0,
                    new PropertyChangedCallback(TheCountProperty_Changed)));

        public int TheCount
        {
            get { return (int)GetValue(TheCountProperty); }
            set { SetValue(TheCountProperty, value); }
        }

        private static void TheCountProperty_Changed(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {

        }

        public UserControl1()
        {
            this.InitializeComponent();
        }

        private void btnLess_Click(object sender, RoutedEventArgs e)
        {
            //lblCount.Text = (Convert.ToInt32(lblCount.Text) - 1).ToString();
            this.Dispatcher.InvokeAsync(
                Windows.UI.Core.CoreDispatcherPriority.Low,
                (s, a) => this.TheCount -= 1,
                this,
                null);
        }

        private void btnMore_Click(object sender, RoutedEventArgs e)
        {
            //lblCount.Text = (Convert.ToInt32(lblCount.Text) + 1).ToString();
            this.Dispatcher.InvokeAsync(
                Windows.UI.Core.CoreDispatcherPriority.Low,
                (s, a) => this.TheCount += 1,
                this,
                null);
        }
    }

    public class IntToStringConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            return value.ToString();
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }

}
于 2012-03-19T05:02:39.877 に答える
0

RichTextBox から継承することで、非常に似たようなことをしました。

http://www.wpfsharp.com/2011/08/01/loading-a-richtextbox-from-an-rtf-file-using-binding-or-a-richtextfile-control/

依存関係プロパティを読み取り専用にしなかったことがわかりました(それが問題かどうかはわかりません)

また、これに入力するつもりだと思います:

private static void TheCountProperty_Changed(DependencyObject source, DependencyPropertyChangedEventArgs e)
{

}
于 2012-03-18T20:03:43.727 に答える