我有一個類叫做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
你能不能展示Clan.Voiced的實現代碼?也許你的OnPropertyChanged的實現是不正確的。 – bradgonesurfing
你是否異步設置Voiced的值?即:你是否啓動一個線程來完成一些工作,然後在作業完成時設置''Clan.Voiced''的值。有時你可以通過非UI線程進行更改。有時你不能。最好的建議是總是在UI線程上更新視圖模型屬性。 – bradgonesurfing
另一個想法。你是否明確地在你的控制上設置了邊框厚度?我認爲這將覆蓋風格中的二傳手。請參閱http://stackoverflow.com/questions/17357117/datatrigger-binding-to-viewmodel-property – bradgonesurfing