2013-03-05 171 views
2

在彈出的窗口中我綁定了一個checkbox.IsChecked模型,但是我希望從窗口顯示時的xaml代碼後面檢查它的狀態。在Windows加載事件後面的代碼中通過名稱檢查複選框時,它尚未設置。我需要做一些特定於UI的事情,這就是爲什麼我需要知道窗口打開時checkboxes的值是什麼,而且我無法從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

+0

發佈您的代碼和XAML – 2013-03-05 20:18:48

+0

提供代碼.... – Dom 2013-03-05 20:32:29

+0

已提供代碼。 – 2013-03-05 20:33:53

回答

2

數據綁定不同步完成,但它被延遲。關於調度程序優先級,請檢查this msdn page。它的執行優先級低於正常的窗口消息,但在渲染之前。

您可以使用比數據綁定定義的優先級低的優先級調用自己的方法,在此方法中,您應該能夠安全地讀取數據綁定值。

我仍然會發現這個醜陋。我寧願直接訂閱PropertyChanged並檢查此屬性,或者甚至更好,將「UI相關代碼」重寫爲數據綁定。

P.S.如果您開始使用事件,請務必取消訂閱,否則可能會發生內存泄漏。

+0

我對原始問題添加了一個可能的解決方案。我不認爲這可能導致內存泄漏..意見? – 2013-03-05 22:11:23

+0

不可以。只有您的意見訂閱了活動,這是我建議的替代解決方案。 – 2013-03-05 22:13:44

0

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) 
     { 
      //... 
     } 
    } 
} 

視圖模型:

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)); 
    } 
} 

enter image description here

相關問題