2011-06-26 44 views
0

我有几个堆栈面板,我只想显示一个被选中(从另一个组合框)。 正如你所看到的,在stackpanel内部有一个组合框,它将选定的值绑定到一个对象。防止从隐藏控件绑定

我的问题是,每个面板更新和重写对象,即使是隐藏的!
是否可以防止隐藏对象的绑定?

<StackPanel x:Name="pnl_1" Orientation="Horizontal" 
      Visibility="{Binding SelectedItem.Name,ElementName=comboProp, Mode=OneWay, ConverterParameter=pnl_1, Converter={StaticResource PanelVisibilityConverter},FallbackValue=Collapsed}"> 
      <ComboBox Height="23" Width="90"         
         ItemsSource="{Binding Source={StaticResource Source1}}"                 
         SelectedValue="{Binding Path=Data.Operand, Converter={StaticResource Converter1}}"> 
      </ComboBox> 

</StackPanel> 


<StackPanel x:Name="pnl_2" Orientation="Horizontal" 
      Visibility="{Binding SelectedItem.Name,ElementName=comboProp, Mode=OneWay, ConverterParameter=pnl_2, Converter={StaticResource PanelVisibilityConverter},FallbackValue=Collapsed}"> 
      <ComboBox Height="23" Width="90"         
         ItemsSource="{Binding Source={StaticResource Source2}}"                 
         SelectedValue="{Binding Path=Data.Operand, Converter={StaticResource Converter2}}"> 
      </ComboBox> 

</StackPanel> 
+0

绑定是绑定;他们不依赖于知名度。绑定到不可见的元素实际上非常有用。无论如何,你只需要另辟蹊径。 –

回答

1

将数据绑定到不可见的UIElement没有任何问题,只要它不会导致性能问题。

如果要根据可见性设置数据绑定,则必须在源代码中执行此操作;你不能在XAML中完成。

下面是一个例子如何创建动态绑定:

Binding myBinding = new Binding("Data.Operand"); 
myBinding.Source = myItemsSource; 
BindingOperations.SetBinding(myComboBox, ComboBox.SelectedValueProperty, myBinding); 

并清除绑定,您将使用

BindingOperations.ClearBinding(myComboBox, ComboBox.SelectedValueProperty); 
0

您可以用DataTriggers绑定条件,这里有一个例子列表框,如果其周围的边框可见,则只设置其ItemsSource

<ListBox Height="100" ScrollViewer.HorizontalScrollBarVisibility="Auto" 
     ScrollViewer.VerticalScrollBarVisibility="Auto"> 
    <ListBox.Style> 
     <Style TargetType="{x:Type ListBox}"> 
      <Style.Triggers> 
       <DataTrigger 
         Binding="{Binding Visibility, RelativeSource={RelativeSource AncestorType=Border}}" 
         Value="Visible"> 
        <Setter Property="ItemsSource" 
          Value="{Binding Source={x:Static local:App.Log}, Path=Buffer}" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </ListBox.Style> 
</ListBox> 
0

是的,那是可能的。 我是在一个类和它的子类的情况下做到的。 我的例子可能不像你的情况,但原则可能很适用。

我有一个A类和两个A的子类,名为AB和AC。 AC和AB都具有超出A的额外属性。

然后是包含As,AB和AC的ObservableCollection。 我必须为集合元素的单个成员显示集合的DataGrid和StackPanel。

对于AB和AC类的额外成员,我在XAML中定义了两个StaticResource StackPanel。 (I总是要显示基类A的成员,因此,这些成员是该结构之外。)

<StackPanel x:Key="AB"...../> 
<StackPanel x:Key="AC"...../> 
<StackPanel x:Key="Nothing"...../> 

这些StackPanels,因为它们是资源,将不能正常运行时绑定:只有当并且如果它们必然会!! 现在我定义了一个ContentControl中,绑定到一个命名属性“SubClassPanel”:

public StackPanel SubClassPanel {get; set; etc...} 

现在我可以编程设置SubClassPanel到eihter的AB资源或AC资源或空,假的StackPanel的资源,如果你只是想显示基类。 这里是子类StackPanels的插入点的XAML:

<ContentControl Content="{Binding SubClassPanel, 
      Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> 

变化完成后,在我的情况下,使用DataGrid事件“的SelectionChanged”。这里是事件管理器:

public void ChangeSection(object sender, SelectionChangedEventArgs e) 
    { 
     // sender is the datagrid 
     if (sender == null) 
      return; 
     // So, SelectedItem can be of class A, AB or AC: 
     var s = (sender as DataGrid).SelectedItem; 

     if (s is AB) 
      (s as AB).SubClassPanel = this.FindResource("AB") as StackPanel; 
     else 
     { 
      if (s is AC) 
       (s as AC).SubClassPanel = this.FindResource("AC") as StackPanel; 
      else 
      { 
       // or show just the base class members: 
       (s).SubClassPanel = this.FindResource("Nothing") as StackPanel; 
      } 
     } 
    }