0

私は WPF アプリケーションを持っており、このアプリではカスタム UserControl を作成しました。このコントロールには、XML から定義済みのレイアウトをロードする機能があります。UserControl に BOOL DependencyProperty を設定して true に設定すると、目的のレイアウトが読み込まれます。さらに、完了時にフラグを False に戻すことで、このフラグを「クリア」したいと考えています。基本的に、PropertyChanged ハンドラー内の依存関係プロパティの値を変更しようとしています。

この例では、プロパティがいつでも false に更新されることはありません。私の実際のアプリケーションでは、トリガーがTrueに設定された最初のときに機能しますが、その後は機能しません。PropertyChanged の間ではなく、LoadTrigger = false を実行しているためだと感じています。

メインフォーム

<Window x:Class="WPF_Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPF_Test"
    Title="MainWindow" Height="350" Width="525">
<Grid>

    <CheckBox IsChecked="{Binding TriggerToLoad}"></CheckBox>

    <local:UC LoadTrigger="{Binding TriggerToLoad}"></local:UC>

    </Grid>
</Window>

メイン フォーム - コード ビハインド

public partial class MainWindow : Window
{
    private TestViewModel VM;

    public MainWindow()
    {
        InitializeComponent();

        this.VM = new TestViewModel();

        this.DataContext = this.VM;

    }
}

ユーザー コントロール - コード ビハインド

public partial class UC : UserControl
{

    public static readonly DependencyProperty LoadTriggerProperty = DependencyProperty.Register("LoadTrigger", typeof(bool), typeof(UC), new  FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, LoadTriggerPropertyChanged));


    public bool LoadTrigger
    {
        get { return (bool)GetValue(LoadTriggerProperty); }
        set { this.SetValue(LoadTriggerProperty, value); }
    }

    private static void LoadTriggerPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            ((UC)source).LoadLayout();
        }
    }

    private void LoadLayout()
    {
        MessageBox.Show("Loading the layout now and then setting DependencyProperty back to false.");

        // TRIED THIS
        this.LoadTrigger = false;

        //TRIED THIS TOO
        //this.SetValue(LoadTriggerProperty, false);

        //TRIED THIS TOO
        //this.SetCurrentValue(LoadTriggerProperty, false);

        //TRIED THIS TOO
        //BindingOperations.GetBindingExpression(this, UC.LoadTriggerProperty).UpdateSource();
    }

    public UC()
    {
        InitializeComponent();
    }
}

ビューモデル

 class TestViewModel : INotifyPropertyChanged
 {



    private bool triggerToLoad;

    public bool TriggerToLoad
    {
        get
        {
            return this.triggerToLoad;
        }

        set
        {
            if (this.triggerToLoad != value)
            {
                this.triggerToLoad = value;
                this.OnPropertyChanged("TriggerToLoad");
            }
        }
    }


    public TestViewModel()
    {
        this.TriggerToLoad = true;
    }



    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (!object.ReferenceEquals(this.PropertyChanged, null))
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

 }
4

2 に答える 2

2

ハンドラーでプロパティを更新すると、未定義の動作につながるようです。

レイアウトの読み込み (およびフラグの更新) を非同期的に延期します。

private static void LoadTriggerPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue)
    {
        //run "async" on the same UI thread:
        Dispatcher.BeginInvoke(((UC)source).LoadLayout);
    }
}
于 2014-03-24T04:52:15.330 に答える
0

propertychanged コールバックhttp://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.coercevalue.aspxDependencyObject.CoerceValue内で依存関係プロパティを通常どのように変更するかを確認する必要があります

于 2014-03-24T13:04:50.190 に答える