我的代码在启动时失败,因为Converter
调用的Multibinding
中的值数组未填充正确的值,但其值为 {{ 1}}。
查看转换器并查看我在哪里收到错误
DependencyProperty.UnsetValue
您可以按照以下网址下载full code或查看我的代码段。
MainWindow.xaml
public class ButtonColorConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
string val1 = string.Format(" {0} ", values[0]);
string val2 = (string)values[1]; **//Here i am getting ==> {DependencyProperty.UnsetValue}**
return val1.Equals(val2)
? Brushes.NavajoWhite
: Brushes.White;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
MainWindow.xaml.cs
<Window x:Class="DataPager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:Local="clr-namespace:DataPager.Convertor_For_BackGround">
<Grid>
<Grid.Resources>
<Local:ButtonColorConverter x:Key="currentPageSetter"/>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="36*" />
<RowDefinition Height="275*" />
</Grid.RowDefinitions>
<ItemsControl Name="pageControl" ItemsSource="{Binding Path=PageCollection}" Grid.Row="0">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border >
<StackPanel>
<ItemsPresenter></ItemsPresenter>
</StackPanel>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel x:Uid="pageItemTemplate">
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button x:Name="pageNumberButton" Margin="3,4" Content="{Binding Path=Page_Number}">
<Button.Background>
<MultiBinding Converter="{StaticResource currentPageSetter}">
<Binding Path="Page_Number" />
<Binding Path="CurrentPage.Page_Number" /> **//This Binding not resolves properly**
</MultiBinding>
</Button.Background>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBox Text="{Binding Path=CurrentPage.Page_Number,Mode=TwoWay, FallbackValue=asdf}" Grid.Row="1" Height="23" Margin="79,62,257,0" Name="textBox1" VerticalAlignment="Top" Width="167" />
</Grid>
</Window>
这是ViewModel Classes。
PageViewModel.cs
public partial class MainWindow : Window
{
public MainWindow()
{
MyPageViewModel = new PageViewModel();
MyPageViewModel.PageCollection.Add(new PageNumberViewModel(string.Format(" {0} ",0)));
MyPageViewModel.PageCollection.Add(new PageNumberViewModel(string.Format(" {0} ",1)));
MyPageViewModel.PageCollection.Add(new PageNumberViewModel(string.Format(" {0} ",2)));
MyPageViewModel.PageCollection.Add(new PageNumberViewModel(string.Format(" {0} ",3)));
InitializeComponent();
}
public PageViewModel MyPageViewModel
{
get
{
return this.DataContext as PageViewModel;
}
set
{
this.DataContext = value;
}
}
}
PageNumberViewModel.cs
public class PageViewModel:ViewModelBase
{
private ObservableCollection<PageNumberViewModel> m_pageCollection = new ObservableCollection<PageNumberViewModel>();
private PageNumberViewModel m_currentPage = new PageNumberViewModel(string.Format(" {0} ",0));
public PageViewModel()
{
m_currentPage = new PageNumberViewModel(string.Format(" {0} ", 1000));
}
public PageNumberViewModel CurrentPage
{
get
{
return this.m_currentPage;
}
set
{
if (m_currentPage == value)
return;
this.m_currentPage = value;
base.OnPropertyChanged("CurrentPage");
}
}
public ObservableCollection<PageNumberViewModel> PageCollection
{
get
{
return this.m_pageCollection;
}
set
{
if (m_pageCollection == value)
return;
this.m_pageCollection = value;
base.OnPropertyChanged("PageCollection");
}
}
}
答案 0 :(得分:9)
在任何ItemsSource中设置列表时,各个项目的DataTemplate的DataContext将列表中的每个项目。
确实您的TextBlock绑定正常工作,因为DataContext设置为您的主对象:PageViewModel
但是在DataTemplate中,DataContext将设置为PageNumberViewModel
,因为这些是您集合中的项目。
因此,绑定到Path=CurrentPage.Page_Number
将导致UnsetValue,因为CurrentPage不是PageNumberViewModel
的属性
希望这能澄清事情!
如果您真的希望绑定到Window的DataContext的CurrentPage属性,请考虑使用ElementName绑定:
给窗口命名,绑定到
<Binding ElementName="name" Path="DataContext.CurrentPage.Page_Number" />
或使用RelativeSource绑定:
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}" Path="DataContext.CurrentPage.Page_Number" />
答案 1 :(得分:6)
看起来您可能没有正确的DataContext来解析路径CurrentPage.Page_Number
。调试此类事情的一种好方法是删除路径,以便可以检查值转换器中的DataContext:
<Binding Path="." />
然后在ButtonColorConverter
中设置断点,并准确了解您要转换的内容。
答案 2 :(得分:6)
DependencyProperty.UnsetValue
只是DependencyProperty类的常量。
您可以这样做:
if (values[1] == DependencyProperty.UnsetValue)
{
return null; // or default value
}
答案 3 :(得分:5)
我也遇到了这个问题,并在另一篇文章(https://stackoverflow.com/a/3139397/500099)中找到了解决方案。关键是使用FallbackValue =“”属性,如下所示:
<MultiBinding Converter="{StaticResource StringFormatConverter}">
<Binding Path="ResultValueControl.Min" FallbackValue=""/>
<Binding Path="Format" />
</MultiBinding>
答案 4 :(得分:0)
我刚刚根据 Mr.Arcturus的建议修改了MainWindow.xaml并且工作正常。
非常感谢 Mr.Arcturus。
你可以在chage
之后看到 ManiWindow.xaml<Window x:Class="DataPager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:Local="clr-namespace:DataPager.Convertor_For_BackGround">
<Grid>
<Grid.Resources>
<Local:ButtonColorConverter x:Key="currentPageSetter"/>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="36*" />
<RowDefinition Height="275*" />
</Grid.RowDefinitions>
<ItemsControl Name="pageControl" ItemsSource="{Binding Path=PageCollection}" Grid.Row="0">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border >
<StackPanel>
<ItemsPresenter></ItemsPresenter>
</StackPanel>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel x:Uid="pageItemTemplate">
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button x:Name="pageNumberButton" Margin="3,4" Content="{Binding Path=Page_Number}">
<Button.Background>
<MultiBinding Converter="{StaticResource currentPageSetter}">
<Binding Path="Page_Number" />
**<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}" Path="DataContext.CurrentPage.Page_Number" />**
</MultiBinding>
</Button.Background>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBox Text="{Binding Path=CurrentPage.Page_Number,Mode=TwoWay, FallbackValue=asdf}" Grid.Row="1" Height="23" Margin="79,62,257,0" Name="textBox1" VerticalAlignment="Top" Width="167" />
<Button Content="Button" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="121,110,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</Window>