首页 > 解决方案 > WPF绑定到父DataContext忽略当前元素的DataContext

问题描述

我想将FirstDate 和 SecondDate StackPanel的Visibility属性绑定到父级的DataContext,而是绑定到当前元素的DataContext。如何忽略此DataContext并设置绑定到父级的DataContext

此外,MonthList 必须忽略父级的DataContext,但它不会这样做。

<StackPanel 
    DataContext="{Binding dateOfProduction}"
    Orientation="Vertical"
    Grid.Row="10"
    Grid.Column="1">
    <StackPanel Orientation="Horizontal">
        <RadioButton Content="One date" Margin="5,0" IsChecked="{Binding Path=DateType, Converter={StaticResource enumBooleanConverter}, ConverterParameter=OneDate}"/>
        <RadioButton Content="Two date" Margin="5,0" IsChecked="{Binding Path=DateType, Converter={StaticResource enumBooleanConverter}, ConverterParameter=TwoDate}"/>
        <RadioButton Content="Not exists" Margin="5,0" IsChecked="{Binding Path=DateType, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Empty}"/>
    </StackPanel>
    <StackPanel DataContext="{Binding Path=FirstDate}" Visibility="{Binding FirstDateExist, Converter={StaticResource booleanToVisibilityConverter}}" Orientation="Horizontal">
        <Label Width="37" Content="Day" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Day}"/>
        <Label Width="46" Content="Month" />
        <ComboBox Width="60"  ItemsSource="{Binding MonthList}" SelectedIndex="{Binding Path=Month}"/>
        <Label Width="29" Content="Year" />
        <TextBox VerticalContentAlignment="Center" Width="32" Text="{Binding Path=Year}"/>
        <Label Width="30" Content="Hour" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Hour}"/>
        <Label Width="51" Content="Minute" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Minute}"/>
    </StackPanel>
    <StackPanel DataContext="{Binding Path=SecondDate}" Visibility="{Binding SecondDateExist, Converter={StaticResource booleanToVisibilityConverter}}" Orientation="Horizontal">
        <Label Width="37" Content="Day" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Day}"/>
        <Label Width="46" Content="Month" />
        <ComboBox Width="60"  ItemsSource="{Binding MonthList}" SelectedIndex="{Binding Path=Month}"/>
        <Label Width="29" Content="Year" />
        <TextBox VerticalContentAlignment="Center" Width="32" Text="{Binding Path=Year}"/>
        <Label Width="30" Content="Hour" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Hour}"/>
        <Label Width="51" Content="Minute" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Minute}"/>
    </StackPanel>
</StackPanel>

下面你可以看到使用的类

public class GoodsDate : PropertyChangedModels
{
    private ComplexDate _FirstDate;
    public ComplexDate FirstDate
    {
        get { return _FirstDate; }
        set { _FirstDate = value; OnPropertyChanged("FirstDate"); }
    }

    private ComplexDate _SecondDate;
    public ComplexDate SecondDate
    {
        get { return _SecondDate; }
        set { _SecondDate = value; OnPropertyChanged("SecondDate"); }
    }
    public bool FirstDateExist
    {
        get => (FirstDate != null);
    }
    public bool SecondDateExist
    {
        get => (SecondDate != null);
    }
}  
public class ComplexDate : PropertyChangedModels
{
    public ComplexDate(int? year = null, int? month = null, int? day = null, int? hour = null, int? minute = null)
    {
        Year = year;
        Month = month;
        Day = day;
        Hour = hour;
        Minute = minute;
    }
    private int? _Year;
    public int? Year
    {
        get { return _Year; }
        set { _Year = value?.LimitToRange(1000, 2999); OnPropertyChanged("Year"); }
    }

    private int? _Month;
    public int? Month
    {
        get { return _Month; }
        set { _Month = value?.LimitToRange(1, 12); OnPropertyChanged("Month"); }
    }

    private int? _Day;
    public int? Day
    {
        get { return _Day; }
        set { _Day = value?.LimitToRange(1, 31); OnPropertyChanged("Day"); }
    }

    private int? _Hour;
    public int? Hour
    {
        get { return _Hour; }
        set { _Hour = value?.LimitToRange(0, 23); OnPropertyChanged("Hour"); }
    }

    private int? _Minute;
    public int? Minute
    {
        get { return _Minute; }
        set { _Minute = value?.LimitToRange(0, 59); OnPropertyChanged("Minute"); }
    }
}

标签: c#wpfdata-binding

解决方案


因为,您已将 DataContext 定义为DataContext="{Binding Path=FirstDate}"在 First/SecondDate,因此该Visibility属性正试图从设置的 DataContext 中解析它。

您的问题有多种解决方案。您可以实施上述之一

1. 使用 Visiblity Property 上的 Relative Source 将绑定设置为 Parent。

Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}, Path=FirstDateExist, Converter={StaticResource booleanToVisibilityConverter}}"

2.

将 StackPanel 包裹到 Grid 并在其上设置 Visiblity。在这种情况下,Visiblity 将绑定到顶部堆栈面板的 DataContext。

<Grid  Visibility="{Binding FirstDateExist, Converter={StaticResource booleanToVisibilityConverter}}">
     <StackPanel DataContext="{Binding Path=FirstDate}" Orientation="Horizontal">
        <Label Width="37" Content="Day" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Day}"/>
        <Label Width="46" Content="Month" />
        <ComboBox Width="60"  ItemsSource="{Binding MonthList}" SelectedIndex="{Binding Path=Month}"/>
        <Label Width="29" Content="Year" />
        <TextBox VerticalContentAlignment="Center" Width="32" Text="{Binding Path=Year}"/>
        <Label Width="30" Content="Hour" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Hour}"/>
        <Label Width="51" Content="Minute" />
        <TextBox VerticalContentAlignment="Center" Width="19" Text="{Binding Path=Minute}"/>
    </StackPanel>
</Grid>

3.

删除DataContext="{Binding Path=FirstDate}"和更改级联控件绑定为Text="{Binding FirstDate.Day}"


推荐阅读