我是一個巨大的XAML noob,我正在用MVVM構建一個WinRT應用程序。基本上,我有一個函數getBackgroundColor(),它返回一個SolidColorBrush,我想讓它在任何給定的時間都可以改變背景顏色,並讓XAML元素注意並更改以匹配getBackgroundColor的新輸出。我知道這應該用綁定來完成,但並不真正瞭解任何在線文檔。有人能像我這樣向我解釋這個5嗎?如何在視圖在屏幕上時修改XAML元素的顏色?
回答
假設你知道屬性和接口是什麼 - 你需要一個屬性來綁定,所以例如你將有一個Border
元素,其綁定設置爲Background={Binding BackgroundBrush}
。然後,您將擁有一個實現了INotifyPropertyChanged
接口的類型的視圖模型對象。該界面有一個事件 - PropertyChanged
,並且當屬性值發生更改時需要引發該事件,因此最常見的情況是,「綁定」屬性將在其設置器中設置爲與以前值不同的值時引發該事件。您的視圖模型的代碼可能是這樣的,那麼:
public event PropertyChangedEventHandler PropertyChanged;
private Brush _backgroundBrush;
public Brush BackgroundBrush
{
get
{
return Brush _backgroundBrush;
}
set
{
if (_backgroundBrush == value)
return;
_backgroundBrush = value;
PropertyChanged(this, new PropertyCHangedEventArgs("BackgroundBrush");
}
}
更常見的,雖然你可以創建一個基類有點像這樣:
abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value))
{
return false;
}
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
}
那麼你的視圖模型看起來是這樣的:
class MyViewModel : BindableBase
{
private Brush _backgroundBrush;
public Brush BackgroundBrush
{
get { return Brush _backgroundBrush; }
set { SetProperty(ref _backgroundBrush, value); }
}
}
這使得您的視圖模型更清晰和更安全重構(您不會傳遞屬性名稱)。
至於在視圖在屏幕上時修改XAML元素的顏色 - 有什麼意義?如果它的顏色只在屏幕上被修改 - 爲什麼不總是使用相同的顏色?此外,如果您正在編寫響應UI中的更改(如滾動)的任何代碼(通常最好是在視圖一側編寫該代碼),在控件,附加行爲或某種服務類中。
翻轉的答案是一個教科書的答案,並將很可能實現您正在尋找的結果。通常對於我來說,我發現MVVM是學術界和現實世界的不斷練習。 MVVM模式在您的場景中運行後,但還有其他方法可以更改UI顏色。這就是談話開始的地方。 ViewModel是否需要知道視圖如何顯示您顯示的內容?如果是的話,堅持另一個答案。如果不是,在拍攝視圖(你的window.xaml和window.xaml.cs)中拍一拍(你的window.xaml和window.xaml.cs)
例如,我有一個顏色轉換器我使用,因爲我決定我的ViewModel不需要知道我的顏色在視圖中切換。因此,在視圖xaml.cs(還是真的,因爲它是一個類,你可以聲明這在任何地方),我定義:
/// <summary>
/// A way to convert the color of text based upon maintenance required
/// </summary>
public class MaintenenceColorConverter : IValueConverter
{
#region Properties
// Properties
public Color NormalColor { get; set; }
public Color NoMaintenanceRequiredColor { get; set; }
#endregion
/// <summary>
/// DEFAULT CONSTRUCTOR
/// </summary>
public MaintenenceColorConverter() { }
/// <summary>
/// Convert the color of the text based upon maintenance required
/// </summary>
/// <returns>
/// The appropriate color property
/// </returns>
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value.ToString() == "No Maintenance Required") return NoMaintenanceRequiredColor.ToString();
return NormalColor.ToString();
}
/// <summary>
/// Not used: NECESSARY FOR IMPLEMENTATION
/// </summary>
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
}
}
現在,這是不漂亮,因爲我覺得我通過檢查那種違反MVVM設計模式在視圖模型的數據視圖中,但我沒關係(讓火焰開始!)。
所以在這一點,所有你需要在你的XAML做,然後是定義你的顏色轉換器:
<UserControl.Resources>
<localColor:MaintenenceColorConverter x:Key="MyColorConverter" NormalColor="Black" NoMaintenanceRequiredColor="Gray" />
</UserControl.Resources>
,然後用它在任何必要!我用它在一個數據網格「灰色」選擇:
<DataGrid.Columns>
<DataGridTextColumn Header="Site Number" Binding="{Binding Path=SiteNo}" IsReadOnly="True" Width="100">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Foreground" Value="{Binding Path=MaintStatus, Converter={StaticResource MyColorConverter}}" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGrid.Columns>
乾杯!
- 1. 如何隨機更改屏幕上每個像素的顏色
- 2. 如何在用戶觸摸屏幕時更改uiview顏色
- 3. 如何在屏幕上定位元素?
- 4. iPad - 在一個視圖上同時更改所有元素的文本顏色
- 5. 得到在屏幕上的顏色
- 6. 在MASM中更改屏幕顏色
- 7. 當元素不在屏幕上時?
- 8. MoveToElement元素剛剛在屏幕上時
- 9. 不在屏幕上時丟失元素
- 10. 我可以更改屏幕上像素的顏色嗎?
- 11. 如何從React Native的屏幕上的像素獲取顏色?
- 12. 如何在x11中獲取屏幕像素的顏色
- 13. 如何檢測屏幕上的像素/顏色
- 14. 在屏幕上出現多種顏色
- 15. 更改啓動屏幕/啓動屏幕顏色和圖像
- 16. 如何在元素出現在屏幕上時啓動動畫?
- 17. 將視圖修改爲等待屏幕
- 18. 在Python3.x中獲取屏幕上像素的顏色
- 19. 如何更改觸摸(屏幕)上的textView(digitalClock)顏色
- 20. 如何在點擊時更改div元素的顏色?
- 21. 如何在滾動時更改菜單元素的顏色?
- 22. CalledFromWrongThreadException:在更改視圖顏色時(Android)
- 23. 如何更改在另一個元素上懸停的元素的顏色
- 24. 如何判斷元素何時最終顯示在屏幕上?
- 25. 如何更改MFMessageComposeViewController元素的顏色?
- 26. 更改屏幕寬度時在導航欄上隱藏元素
- 27. 提取屏幕像素的顏色請
- 28. 在屏幕Java上獲取像素顏色?
- 29. 屏幕上的顏色反轉在OS X中如何工作?
- 30. 如何在ActionScript 3.0中更改屏幕背景顏色?
看起來很好,雖然我不確定從Color到Brush的隱式轉換是否可以在WinRT/XAML中工作(DataGrid必須是WPF,對嗎?)。從視圖中檢查視圖模型是非常好的,但是在代碼中比較字符串看起來並不是最佳實踐。在視圖模型方面使用'bool'或'enum'可能會更好。無論如何,有很多方法可以實現相同的目標。在虛擬機上使用Color或Brush屬性並不是最好的解決方案,但它可能是最簡單的。您也可以根據具體情況使用轉換器或VisualStateManager。 +1 – 2014-11-07 00:30:08
我喜歡這個答案,但是當我嘗試實現它時失敗了,在ConvertBack對象上發生錯誤不會返回任何內容。建議? – Brady 2015-09-21 05:31:46
對不起,這是一個黑客,但你可以返回「拋出新的NotImplementedException();」但理想情況下,您應該做與您在轉換方法中做的相反的事情。更多可以在[這裏]找到(https://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.convertback%28v=vs.110%29.aspx) – Stunna 2015-09-24 20:34:55