数据模板中的可见性绑定问题

本文关键字:可见性 绑定 问题 数据 | 更新日期: 2023-09-27 18:34:46

我不知道为什么,但我的可见性绑定不仅在数据模板中起作用。我忘记了什么吗?编辑:所有绑定(除了这个完美地工作(这就是结构。

<Window>
<Grid>
<Grid>
<Grid Grid.Row="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>                
                  <ItemsControl x:Name="Targets" Margin="0,4,0,4">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid Margin="0,5,0,5">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="Auto" />
                                </Grid.RowDefinitions>
                                <TextBox TextWrapping="Wrap" Foreground="{Binding Foreground, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" Text="{Binding Address, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" Tag="{Binding}" PreviewKeyDown="ChangeLocationAddress" PreviewGotKeyboardFocus="TxtGotKeyboardFocusHandler" LostKeyboardFocus="ChangeLocationAddress" />
                                <Button Margin="2,0,0,0" Grid.Column="1" Content=" ↑ " Click="MoveLocationUp" Visibility="Visible" /> 
                                <Button Margin="2,0,0,0" Grid.Column="2" Content=" ↓ "  Click="MoveLocationDown" Visibility="{Binding Path = UpDownButtonVisibility, UpdateSourceTrigger=PropertyChanged}"/>
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
           <Button x:Name="btnNewAddress" Grid.Row="1" Content="Neues Ziel hinzufügen" Margin="0,4,0,4" Visibility="{Binding Path=TargetButtonVisibility}"/>
        </Grid>
</Grid></Grid></Grid></Window>

代码隐藏:

public MapView(){
 this.DataContext = this.ViewModel = new MapVM();
 this.InitializeComponent();
 this.Targest.Itemssource = this.ViewModel.ToLocations;
}

视图模型:

public MapVM()
        {   this.UpDownButtonVisibility = Visibility.Collapsed;
            this.TargetButtonVisibility = Visibility.Collapsed;
        }
 private Visibility _UpDownButtonVisibility;
    /// <summary>
    /// Property Visibility für "↓" und "↑"
    /// </summary>
    public Visibility UpDownButtonVisibility
    {
        get { return _UpDownButtonVisibility; }
        set
        {
            this._UpDownButtonVisibility = value;
            NotifyPropertyChanged("UpDownButtonVisibility");
        }
    }
public Visibility TargetButtonVisibility { get; set; }

编辑:程序输出: 绑定表达式路径错误:"UpDownButtonVisibility"属性在"对象"位置"(哈希代码=-794088449("上找不到。绑定表达式:路径=向上向下按钮可见性;DataItem='Location' (hashCode=-794088449(;目标元素是"按钮"(名称="(;目标属性为"可见性"(类型"可见性"( 1.10s

有什么建议吗?

数据模板中的可见性绑定问题

我在代码中找不到 PropertyChanged 事件处理程序和对它的调用。将 INotifyPropertyChanged 添加到您的 DataContext 对象,它应该可以工作

就个人而言,我会将可见性建模为布尔值,并使用 WPF 附带的 BooleasnToVisibility 转换器。

将字符串更改为可见性

public Visibility UpDownButtonVisibility { get; set; }
this.UpDownButtonVisibility = Visibility.Collapsed;

将 INPC 和绑定添加到视图模型。

这是工作示例:

XAML

<Window x:Class="ItemsControlDataTemplate.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:ItemsControlDataTemplate"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <ItemsControl x:Name="Targets" Margin="0,4,0,4" ItemsSource="{Binding Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="0,5,0,5">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <TextBox TextWrapping="Wrap" Foreground="{Binding Foreground, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" Text="{Binding Address, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" Tag="{Binding}" />
                        <Button Margin="2,0,0,0" Grid.Column="1" Content=" ↑ " Visibility="Visible" />
                        <Button Margin="2,0,0,0" Grid.Column="2" Content=" ↓ "   Visibility="{Binding Path=UpDownButtonVisibility}"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

C#

class MainWindowViewModel : INotifyPropertyChanged
{
    ObservableCollection<MapVM> _items = new ObservableCollection<MapVM>();
    public ObservableCollection<MapVM> Items { get { return _items; } }

    public MainWindowViewModel()
    {
        Items.Add(new MapVM() { UpDownButtonVisibility = Visibility.Visible, Address = "1111111" });
        Items.Add(new MapVM() { UpDownButtonVisibility = Visibility.Collapsed, Address = "222222" });
        Items.Add(new MapVM() { UpDownButtonVisibility = Visibility.Visible, Address = "33333333" });
    }
    public event PropertyChangedEventHandler PropertyChanged;
}


class MapVM : INotifyPropertyChanged
{
    public MapVM()
    {
        this.UpDownButtonVisibility = Visibility.Collapsed;
        this.TargetButtonVisibility = Visibility.Collapsed;
    }
    private Visibility _upDownButtonVisibility;
    public Visibility UpDownButtonVisibility
    {
        get { return _upDownButtonVisibility; }
        set
        {
            _upDownButtonVisibility = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(UpDownButtonVisibility)));
        }
    }

    private Visibility _targetButtonVisibility;
    public Visibility TargetButtonVisibility
    {
        get { return _targetButtonVisibility; }
        set
        {
            _targetButtonVisibility = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TargetButtonVisibility)));
        }
    }
    private string _address;
    public string Address
    {
        get { return _address; }
        set
        {
            _address = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Address)));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

TargetButtonVisibility绑定的DataContext是主要MapVM。这工作正常。

DataTemplate中的DataContext不是MapVM,而是模板显示的项目

由于您没有在您的ItemsControl上提供任何ItemsSource约束力,我们无法知道这实际上是什么。

此外,正如 unkreativ 指出的那样,不要在 VM 中使用可见性,因为这是一种与视图相关的类型。改用 bool 并调用属性 IsUpDownButtonVisible 或类似属性。

编辑:假设你确实绑定到你的单个MapVM,你可以使用RelativeSource来查找父ItemsControl

<Button Margin="2,0,0,0" 
        Grid.Column="2" 
        Content=" ↓ "  
        Click="MoveLocationDown" 
        Visibility="{Binding DataContext.UpDownButtonVisibility,
                             RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}"/>

但是,由于您已经命名了ItemsControl(Targets(,因此您可以简单地按名称引用它:

<Button Margin="2,0,0,0" 
        Grid.Column="2" 
        Content=" ↓ "  
        Click="MoveLocationDown" 
        Visibility="{Binding DataContext.UpDownButtonVisibility,
                             ElementName=Targets}"/>