2011-07-22 17 views
8

Multibinding tarafından çağrılan Converter değerler dizisi uygun değere dolu amaDependencyProperty.UnsetValue bir değere sahip olmadığı için benim kod başlangıçta başarısız olur. i hatayıWPF MultiBinding başarısız ==> 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(); 
     } 
    } 

alma nerede

Sen full code indirmek ya da benim kodları aşağıda başına pasajı görebilirsiniz Converter bir göz ve ayrıca bkz.

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

Ve bu ViewModel Sınıflar olduğunu.

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 Yolu CurrentPage.Page_Number çözmek için doğru DataContext'i yok ediyor gibi

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"); 
      } 
     } 

    } 
+1

Hatta koduna derin bakmadan sen yürütmek (string) değerleri [1] (her zaman "sihirli numaralar" dikkat öncesinde, şiddetle ilk teste öneririm) a) değerleri []! = null ve b) gerçekten dizin 1'de bir nesne (veya en azından değerler.Length> 0) içeriyorsa ve c) bu nesne istenen STRING türüne gerçekten sahipse. Tetikleyiciler sık ​​sık ateşleyebilir ve beklediğinizden farklı değerler içerebilir, bu yüzden bunları doğrudan kullanmadan önce Dizilerinizi kontrol edin. Bu, istisnalarınızı engellemenize yardımcı olabilir. –

cevap

7

Herhangi bir ItemsSource içinde bir liste ayarladığınızda, DataTemplate'ın her bir öğe için DataContext'i, listenin her bir öğesi olacaktır.

Doğru senin TextBlock DataContext ana nesneye ayarlandığı için, düzgün çalıştığını bağlama o:

Ama bunlar Koleksiyonunuzdaki öğelerdir beri DataTemplate DataContext'i, PageNumberViewModel olarak ayarlanır PageViewModel.

halde, CurrentPage bu şeyleri açıklık PageNumberViewModel

Umut bir özellik olmadığı için, UnsetValue için sonuçlanacaktır Path=CurrentPage.Page_Number bağlanma!bağlayıcı bir RelativeSource

penceresi bir ad verin, bağlama

<Binding ElementName="name" Path="DataContext.CurrentPage.Page_Number" /> 

veya kullanmak: Eğer gerçekten Pencere DataContext ait CurrentPage özelliğine bağlamak isterseniz

, bağlayıcı bir elementName kullanmayı düşünün

<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}" Path="DataContext.CurrentPage.Page_Number" /> 
+1

Çok teşekkür ederim ........ Tam olarak istediğim bu ... önerdiğin gibi bağlama yolunu yeni değiştirdim ... ve çözülmekte olan problemi ..... bir kez daha çok teşekkür ederim. ..... –

+0

Rica ederim! Yardımcı olduğuma sevindim! :) – Arcturus

+1

İnanılmaz! İlginç bir konu. Bana da yardımcı oldu @Arcturus – Ramankingdom

5

.

<Binding Path="." /> 

Sonra ButtonColorConverter bir kesme noktası ayarlamak ve tam olarak ne çalışıyorsunuz de bakabilirsiniz: bu tür bir şey ayıklama iyi bir yolu, değer dönüştürücü içinde DataContext'i denetleyebilmesi için bu yolu kaldırmaktır dönüştürmek.

+0

Bu "CurrentPage.Page_Number" öğesini "TextBox" ın "Text" özelliğine bağladığımda kodumda çalışıyor ve iyi çalışıyor. Sadece Convertor –

+1

ile Multibinding'de kullanırsak, bu yalnızca istisna verir, ancak Content.Bontground'un DataContext'ini etkileyen Content = "{Binding Path = Page_Number}" içeriğiniz bağlayıcı değil mi? – ColinE

+0

Ya @ColinE, önerdiğim şekilde önerdiğimde ... 'DataCagerext' olarak atadığım {DataPager.ViewModel.PageViewModel} 'yerine {DataPager.ViewModel.PageNumberViewModel}' aldım. ..... –

0

sadece Mr.Arcturus en öneri başına ve onun wo olarak MainWindow.xaml içinde DeğiĢmesi iyi rüşvet.

Teşekkür ederiz Mr.Arcturus.

Eğer chage

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

Ben de bu sorunla karşılaştı ve başka yazı (https://stackoverflow.com/a/3139397/500099) bir çözüm bulduk sonra ManiWindow.xaml görebilirsiniz. Anahtar böyle FallbackValue = "" özelliği kullanmaktır:

<MultiBinding Converter="{StaticResource StringFormatConverter}"> 
    <Binding Path="ResultValueControl.Min" FallbackValue=""/> 
    <Binding Path="Format" /> 
</MultiBinding> 
5

DependencyProperty.UnsetValue sadece DependencyProperty sınıfına bir sabittir.

Böyle bir şey yapabilirsiniz:

if (values[1] == DependencyProperty.UnsetValue) 
{ 
    return null; // or default value 
} 
+1

Bir senaryoya bağlı olmayan mükemmel cevap! – usefulBee