转换器中的 WPF MultiBinding 失败 ==> DependencyProperty.UnsetValue
我的代码在启动时失败,因为由 Multibound
调用的 Converter
中的值数组未填充正确的值,但值为 DependencyProperty.UnsetValue
。
看看转换器,也看看我在哪里遇到错误
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
<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>
MainWindow.xaml.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;
}
}
}
这是 ViewModel 类。
PageViewModel.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");
}
}
}
PageNumberViewModel。计算机科学
public class PageNumberViewModel : ViewModelBase
{
private string m_pageNumber;
public PageNumberViewModel()
{
}
public PageNumberViewModel(string pageNumgerArg)
{
this.m_pageNumber = pageNumgerArg;
}
public string Page_Number
{
get { return m_pageNumber; }
set
{
if (m_pageNumber == value)
return;
m_pageNumber = value;
OnPropertyChanged("PageNumber");
}
}
}
My code fails at at startup because the values array in the Converter
that is called by the Multibinding
is not filled with proper value but have a value of DependencyProperty.UnsetValue
.
have a look at Convertor and also see where i getting error
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();
}
}
You can download full code or see my codes snippet as per below.
MainWindow.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 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>
MainWindow.xaml.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;
}
}
}
And this is ViewModel Classes.
PageViewModel.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");
}
}
}
PageNumberViewModel.cs
public class PageNumberViewModel : ViewModelBase
{
private string m_pageNumber;
public PageNumberViewModel()
{
}
public PageNumberViewModel(string pageNumgerArg)
{
this.m_pageNumber = pageNumgerArg;
}
public string Page_Number
{
get { return m_pageNumber; }
set
{
if (m_pageNumber == value)
return;
m_pageNumber = value;
OnPropertyChanged("PageNumber");
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当您在任何 ItemsSource 中设置列表时,各个项目的 DataTemplate 的 DataContext 将是列表中的每个项目。
确实,您的 TextBlock 绑定工作正常,因为 DataContext 设置为您的主对象:
PageViewModel
但在您的 DataTemplate 中,DataContext 将设置为
PageNumberViewModel
,因为这些是您收藏的物品。因此,绑定到
Path=CurrentPage.Page_Number
将导致 UnsetValue,因为 CurrentPage 不是PageNumberViewModel
的属性希望这能澄清问题!
如果您确实希望绑定到窗口 DataContext 的 CurrentPage 属性,请考虑使用 ElementName 绑定:
为窗口指定名称,绑定到
或使用relativesource 绑定:
When you set a list in any ItemsSource, the DataTemplate's DataContext for the individual items will each item of the list.
True that your TextBlock binding is working correctly, because the DataContext is set to your main object:
PageViewModel
But in your DataTemplate the DataContext will be set to
PageNumberViewModel
, since these are the items in your collection.Therefor, the binding to
Path=CurrentPage.Page_Number
will result to UnsetValue, because CurrentPage is not a property ofPageNumberViewModel
Hope this clarifies things!
If you truly wish to bind to the CurrentPage property of your Window's DataContext, consider using an ElementName binding:
Give window a name, bind to
or use a RelativeSource binding:
您似乎没有正确的 DataContext 来解析路径
CurrentPage.Page_Number
。调试此类事情的一个好方法是删除路径,以便您可以检查值转换器中的 DataContext:然后在
ButtonColorConverter
中设置一个断点,并准确查看您正在尝试的内容进行转换。It looks like you might not have the correct DataContext to resolve the path
CurrentPage.Page_Number
. A good way of debugging this sort of thing is to remove the path so that you can inspect the DataContext within your value converter:Then set a breakpoint in your
ButtonColorConverter
and have a look at exactly what you are trying to convert.DependencyProperty.UnsetValue
只是 DependencyProperty 类的常量。你可以这样做:
DependencyProperty.UnsetValue
is merely a constant on the DependencyProperty class.You can do something like this :
我也遇到了这个问题,并在另一篇文章中找到了解决方案(https://stackoverflow.com/a/3139397/500099 )。关键是使用 FallbackValue="" 属性,如下所示:
I also encountered this problem and found a solution in another post (https://stackoverflow.com/a/3139397/500099). The key is to use the FallbackValue="" property like this:
我刚刚按照 Mr.Arcturus 的建议更改了 MainWindow.xaml,并且工作正常。
非常感谢Mr.Arcturus。
更改后就可以看到ManiWindow.xaml
I have just Changed in MainWindow.xaml as per Mr.Arcturus's suggestion and its working fine.
Thank you so much Mr.Arcturus.
you can see ManiWindow.xaml after chage