2

ポップアップウィンドウにcheckbox.IsCheckedモデルがバインドされていますが、ウィンドウが表示されたときにxamlコードビハインドからモデルの状態を確認したいと思います。Windowsのロードされたイベントからコードビハインドで名前でチェックボックスをチェックすると、まだ設定されていません。私がしなければならないUI固有のことがいくつかあります。そのため、ウィンドウが開いたときにチェックボックスの値が何であるかを知る必要があり、checkbox.IsCheckedがバインドされているモデルからこれを実行することはできません。

モデルのプロパティはポップアップウィンドウが開くずっと前に設定されているため、バインディングが存在しないという問題はありません。Loadedイベントが発生すると、ウィンドウはバインディングなどすべてを使用できるようになると思いましたが、そうではないようです。

Xaml:

<RefinedRibbonControls:RefinedRibbonGroup Header="Show Graphs">
                    <StackPanel x:Name="panelVisibilities">
                        <CheckBox Content="Show/hide" x:Name="myCheckBox"                                 
                                  IsChecked="{Binding Path=Processor.Model.IsItemVisible}"
                                  Click="GraphVisibilityClickEvent"
                                  HorizontalAlignment="Left"/>
...etc

モデルのプロパティ:

public bool IsItemVisible
        {
            get { return _isItemVisible ; }
            set
            {
                if (_isItemVisible != value)
                {
                    _isItemVisible = value;
                    _propertyChanger.FirePropertyChanged(this, m => m.IsItemVisible);
                }
            }
        }

Xamlコードビハインドのイベント:

private void WindowLoadedEvent(object sender, RoutedEventArgs e)
        {
            if(myCheckBox.IsChecked.Value)
            {
                // Do UI Related Stuff
            }
         }

バインディングは正常に機能し、ウィンドウが表示されたときに値が表示されます。問題は、ウィンドウが読み込まれたイベントでバインディングの値を取得できないことです。

編集:私が見つけた可能な解決策ですが、それが最善の方法かどうかはわかりません。xamlコードビハインドのコンストラクターから次のメソッドを呼び出しました。

private void SetupInitialVisibility()
        {
            //Fire after everything is loaded.
            Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() =>
            {
                IEnumerable<CheckBox> elements = this.panelVisibilities.Children.OfType<CheckBox>().ToList();
                foreach (CheckBox checkBox in elements)
                {
                    if (checkBox.IsChecked != null && checkBox.IsChecked.Value == false)
                    {
                        //Do work
                    }
                }


            }));
        }

で見つかりました:https ://stackoverflow.com/a/1746975/1253746

4

2 に答える 2

3

データバインディングは同期的に実行されませんが、遅延します。ディスパッチャの優先順位については、このmsdnページを確認してください。これは、通常のウィンドウメッセージよりも低い優先度で実行されますが、レンダリングの前に実行されます。

データバインディングに定義されている優先度よりも低い優先度で自分自身でメソッドを呼び出すことができます。このメソッドでは、データバインドされた値を安全に読み取ることができるはずです。

私はまだこれを醜いと思うでしょう。このプロパティを直接サブスクライブしてPropertyChanged確認するか、さらに良いことに、「UI関連のコード」をデータバインディングとして書き直したいと思います。

PSイベントの消費を開始する場合は、必ずサブスクライブを解除してください。そうしないと、メモリリークが発生する可能性があります。

于 2013-03-05T22:06:28.953 に答える
1

DataBindingは、Loadedイベントの前に配置する必要があると思います。

いつ、どのようにDataContextを設定しますか?そして、viewmodelプロパティがすでに設定されていることを確信していますか?

以下は機能します。可能であれば、コードをこれに合わせてみてください。

Xaml:

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

    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <CheckBox x:Name="myCheckBox" IsChecked="{Binding IsItemVisible}" />
    </Grid>
</Window>

コードビハインド:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        this.Loaded += MainWindow_Loaded;
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        if (myCheckBox.IsChecked.Value)
        {
            //...
        }
    }
}

ViewModel:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool isItemVisible;
    public bool IsItemVisible { get { return isItemVisible; } set { isItemVisible = value; OnPropertyChanged("IsItemVisible"); } }


    public ViewModel()
    {
        this.IsItemVisible = true;
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

ここに画像の説明を入力してください

于 2013-03-05T22:17:22.087 に答える