Предотвратить привязку от скрытого контроля - PullRequest
0 голосов
/ 26 июня 2011

У меня есть пара панелей стека, я хочу показать только ту, которая была выбрана (из другого списка). Как видите, внутри стековой панели есть поле со списком, которое связывает выбранное значение с объектом.

Моя проблема в том, что каждая панель обновляет и переопределяет объект, даже тот, который скрыт!
Можно ли предотвратить связывание со скрытыми объектами?

<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>

Ответы [ 3 ]

1 голос
/ 26 июня 2011

Нет ничего плохого в том, что привязка данных к невидимому элементу UIElement не вызывает проблем с производительностью.

Если вы хотите установить привязку данных в зависимости от видимости, вы должны сделать это в своем исходном коде; вы не можете сделать это в XAML.

Вот пример того, как динамически создать привязку:

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

И для очистки привязки вы бы использовали

BindingOperations.ClearBinding(myComboBox, ComboBox.SelectedValueProperty);
0 голосов
/ 23 января 2018

Да, это возможно.Я сделал это в ситуации класса и его подклассов.Мой пример может не соответствовать вашей ситуации, но принцип вполне может применяться.

У меня есть класс A и два подкласса A, названные AB и AC.И AC, и AB обладают дополнительными свойствами, превосходящими свойства A.

. Затем существует ObservableCollection, содержащая As, AB и AC.Мне пришлось отобразить DataGrid коллекции и StackPanel для отдельных элементов элементов Collection.

Для дополнительных членов класса AB и AC я определил две статические панели StaticResource в XAML.(Мне всегда приходилось отображать элементы базового класса A, поэтому эти члены находятся за пределами этой конструкции.)

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

Эти StackPanels, поскольку они являются ресурсами, обычно не связываются во время выполнения: только когда и еслиони обязаны!Теперь я определяю ContentControl, привязанный к свойству с именем «SubClassPanel»:

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

Теперь я могу программно установить SubClassPanel для любого ресурса AB или ресурса AC или пустого, фиктивного ресурса StackPanel, если вы толькохочу показать базовый класс.Вот XAML для точки вставки подкласса StackPanels:

 <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;
            }
        }
    }
0 голосов
/ 26 июня 2011

Вы можете сделать привязки условными, используя DataTriggers, вот пример ListBox, у которого установлен 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...