2017-01-25 18 views
0

我有一個類叫做Clan。一個屬於氏族的財產是一個有聲的,默認爲虛假的。在Dependency屬性內更新屬性不會顯示在視圖中

我有一個觀點,ClanUI。這有一個依賴性屬性Clan類型。

在VM中,我有型家族,其被傳遞給視圖作爲依賴屬性的屬性:

<UC:ClanUI Clan="{Binding Meilyr}" /> 

內ClanUI視圖,我有一個圖像,該圖像中的調用命令VM。它使用正確的DataContext:

... 
<i:InvokeCommandAction Command="{Binding DataContext.ClanVoiced, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding Clan.Name}" /> 
... 

在VM內的命令,我設置的濁在屬性Meilyr,其被傳遞到爲true視圖作爲DP從假值。

在視圖中,我有一個datatrigger,它應該反映Voice中的變化。

<Style TargetType="{x:Type Border}"> 
    <Setter Property="BorderThickness" Value="2" /> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Clan.Voiced}" Value="false"> 
      <Setter Property="BorderThickness" Value="0" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

我已經嘗試開始濁默認爲真,這顯示了2的邊框厚度。所以綁定工作正常。我已經調試過,並且代碼正確地擊中了虛擬機,Meilyr有聲屬性被更改爲true,並正確調用OnPropertyChanged。

我不知道爲什麼,當我從虛擬機更改DP內的值時,它並不反映視圖內的這些更改。

編輯:提供更多的代碼的要求

這裏是邊境和視圖中的圖像。單擊圖像調用在VM

<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"> 
    ... 
    <Border BorderBrush="Red" Margin="5"> 
     <Image Source="{Binding Clan.Image, FallbackValue='../Media/Clans/Meilyr.png'}" Height="40" VerticalAlignment="Center"> 
      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="MouseUp"> 
        <i:InvokeCommandAction Command="{Binding DataContext.ClanVoiced, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding Clan.Name}" /> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
     </Image> 
     <Border.Style> 
      <Style TargetType="{x:Type Border}"> 
       <Setter Property="BorderThickness" Value="2" /> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding Clan.Voiced}" Value="false"> 
         <Setter Property="BorderThickness" Value="0" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </Border.Style> 
    </Border> 
    ... 
</Grid> 

命令,這裏是依賴屬性在xaml.cs:

public Clan Clan 
    { 
     get { return (Clan)GetValue(ClanProperty); } 
     set { SetValue(ClanProperty, value); } 
    } 
    public static readonly DependencyProperty ClanProperty = 
     DependencyProperty.Register("Clan", typeof(Clan), 
     typeof(ClanUI), new PropertyMetadata(null)); 
在主視圖

,這裏是我如何放置視圖:

<UC:ClanUI Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" Clan="{Binding Meilyr}" /> 

,這裏是從虛擬機的一些片段:

private Clan _Meilyr = new Clan(); 
    public Clan Meilyr 
    { 
     get 
     { 
      return _Meilyr; 
     } 
     set 
     { 
      _Meilyr = value; 
      OnPropertyChanged("Meilyr"); 
     } 
    } 

... 

private ICommand _ClanVoiced; 
public ICommand ClanVoiced 
{ 
    get 
    { 
     if (_ClanVoiced == null) 
     { 
      _ClanVoiced = new RelayCommand(ClanVoicedEx, null); 
     } 
     return _ClanVoiced; 
    } 
} 
private void ClanVoicedEx(object p) 
{ 
    if(Clans.FindAll(C => C.Voiced).Count >= 2) 
    { 
     //TODO 
    } 
    //Clans.First(C => C.Name == p.ToString()).Voiced = true; //<< This is how I will eventually be doing it, the next line was to ensure I was setting the correct thing. 
    Meilyr.Voiced = true; //When debugging, when I click the image this line is hit, and after it has executed, inspecting Meilyr.Voiced shows it as being true. 
} 

最後,這裏是Clan.cs中的Voiced屬性,以及OnPropertyChanged。

private bool _Voiced = false; //<< When I default this to true instead, it displays how I expect in the view. Initial bindings seem to work fine. It just doesn't seem to know when Voiced changes for some reason... 
public bool Voiced 
{ 
    get 
    { 
     return _Voiced; 
    } 
    set 
    { 
     _Voiced = value; 
     OnPropertyChanged("Voiced"); 
    } 
} 

... 

#region INotifyPropertyChanged Members 

public event PropertyChangedEventHandler PropertyChanged; 

private void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler = PropertyChanged; 

    if (handler != null) 
    { 
     if (handler.Target is CollectionView) 
     { 
      ((CollectionView)handler.Target).Refresh(); 
     } 
     else 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

#endregion 
+0

你能不能展示Clan.Voiced的實現代碼?也許你的OnPropertyChanged的實現是不正確的。 – bradgonesurfing

+0

你是否異步設置Voiced的值?即:你是否啓動一個線程來完成一些工作,然後在作業完成時設置''Clan.Voiced''的值。有時你可以通過非UI線程進行更改。有時你不能。最好的建議是總是在UI線程上更新視圖模型屬性。 – bradgonesurfing

+0

另一個想法。你是否明確地在你的控制上設置了邊框厚度?我認爲這將覆蓋風格中的二傳手。請參閱http://stackoverflow.com/questions/17357117/datatrigger-binding-to-viewmodel-property – bradgonesurfing

回答

1

確保Clan類實現INotifyPropertyChanged接口並在Voiced屬性的setter中引發PropertyChanged事件。

由於您綁定到Clan.Voiced屬性,因此定義Meilyr和ClanVoided屬性的視圖模型類實現INotifyPropertyChanged接口並不重要。

+0

剛剛意識到我忘了添加這段代碼,我在PropertyChanged和Voiced的屬性中添加了這些內容,我必須將其添加到原始文章中。它應該盡我所能地工作,但沒有。 – pingu2k4

+1

Ohhhh ....我現在看到它。我沒有把':INotifyPropertyChanged'放進去......我現在覺得很蠢......編輯 - 當我把它放在...當然...>。< – pingu2k4

0

請問您可以發表ViewModel代碼嗎?

我假設你正在更新Clan屬性的改變,但不是Voice屬性的改變。換句話說,Voiced需要成爲一個擁有自己財產的財產改變了事件發生。

+0

用代碼更新。有聲有自己的onpropertychanged,並且作爲以前的測試(現在從代碼中取出),我嘗試在運行映像單擊命令時手動從VM調用Clan實例上的Onpropertychanged(「濁音」),但仍然沒有任何結果。 – pingu2k4